$(base_adaptor_src_dir)/environment-options.cpp \
$(base_adaptor_src_dir)/fps-tracker.cpp \
$(base_adaptor_src_dir)/frame-time.cpp \
+ $(base_adaptor_src_dir)/render-helper.cpp \
+ $(base_adaptor_src_dir)/render-request.cpp \
$(base_adaptor_src_dir)/render-thread.cpp \
$(base_adaptor_src_dir)/thread-controller.cpp \
$(base_adaptor_src_dir)/thread-synchronization.cpp \
--- /dev/null
+/*
+ * Copyright (c) 2015 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 "render-helper.h"
+
+// EXTERNAL INCLUDES
+#include <dali/integration-api/debug.h>
+
+// INTERNAL INCLUDES
+#include <base/interfaces/adaptor-internal-services.h>
+#include <base/display-connection.h>
+
+namespace Dali
+{
+
+namespace Internal
+{
+
+namespace Adaptor
+{
+
+RenderHelper::RenderHelper( AdaptorInternalServices& adaptorInterfaces )
+: mGLES( adaptorInterfaces.GetGlesInterface() ),
+ mEglFactory( &adaptorInterfaces.GetEGLFactoryInterface()),
+ mEGL( NULL ),
+ mSurfaceReplaced( false )
+{
+ // set the initial values before render thread starts
+ mSurface = adaptorInterfaces.GetRenderSurfaceInterface();
+
+ mDisplayConnection = Dali::DisplayConnection::New();
+}
+
+RenderHelper::~RenderHelper()
+{
+ if (mDisplayConnection)
+ {
+ delete mDisplayConnection;
+ mDisplayConnection = NULL;
+ }
+
+ mEglFactory->Destroy();
+}
+
+void RenderHelper::Start()
+{
+ if( mSurface )
+ {
+ mSurface->StartRender();
+ }
+}
+
+void RenderHelper::Stop()
+{
+ if( mSurface )
+ {
+ // Tell surface we have stopped rendering
+ mSurface->StopRender();
+
+ // The surface will be destroyed soon; this pointer will become invalid
+ mSurface = NULL;
+ }
+}
+
+void RenderHelper::ConsumeEvents()
+{
+ mDisplayConnection->ConsumeEvents();
+}
+
+void RenderHelper::InitializeEgl()
+{
+ mEGL = mEglFactory->Create();
+
+ DALI_ASSERT_ALWAYS( mSurface && "NULL surface" );
+
+ // Initialize EGL & OpenGL
+ mDisplayConnection->InitializeEgl( *mEGL );
+ mSurface->InitializeEgl( *mEGL );
+
+ // create the OpenGL context
+ mEGL->CreateContext();
+
+ // create the OpenGL surface
+ mSurface->CreateEglSurface(*mEGL);
+
+ // Make it current
+ mEGL->MakeContextCurrent();
+}
+
+void RenderHelper::ReplaceSurface( RenderSurface* newSurface )
+{
+ // This is designed for replacing pixmap surfaces, but should work for window as well
+ // we need to delete the egl surface and renderable (pixmap / window)
+ // Then create a new pixmap/window and new egl surface
+ // If the new surface has a different display connection, then the context will be lost
+ DALI_ASSERT_ALWAYS(newSurface && "NULL surface");
+
+ mDisplayConnection->InitializeEgl(*mEGL);
+
+ newSurface->ReplaceEGLSurface(*mEGL);
+
+ // use the new surface from now on
+ mSurface = newSurface;
+ mSurfaceReplaced = true;
+}
+
+void RenderHelper::ShutdownEgl()
+{
+ if( mSurface )
+ {
+ // give a chance to destroy the OpenGL surface that created externally
+ mSurface->DestroyEglSurface( *mEGL );
+ }
+
+ // delete the GL context / egl surface
+ mEGL->TerminateGles();
+}
+
+bool RenderHelper::PreRender()
+{
+ if( mSurface )
+ {
+ mSurface->PreRender( *mEGL, mGLES );
+ }
+ mGLES.PreRender();
+ return true;
+}
+
+void RenderHelper::PostRender()
+{
+ // Inform the gl implementation that rendering has finished before informing the surface
+ mGLES.PostRender();
+
+ if( mSurface )
+ {
+ // Inform the surface that rendering this frame has finished.
+ mSurface->PostRender( *mEGL, mGLES, mDisplayConnection, mSurfaceReplaced );
+ }
+ mSurfaceReplaced = false;
+}
+
+} // namespace Adaptor
+
+} // namespace Internal
+
+} // namespace Dali
--- /dev/null
+#ifndef __DALI_INTERNAL_RENDER_HELPER_H__
+#define __DALI_INTERNAL_RENDER_HELPER_H__
+
+/*
+ * Copyright (c) 2015 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.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include <egl-interface.h>
+#include <render-surface.h> // needed for Dali::RenderSurface
+
+namespace Dali
+{
+
+class RenderSurface;
+class DisplayConnection;
+
+namespace Integration
+{
+class GlAbstraction;
+}
+
+namespace Internal
+{
+namespace Adaptor
+{
+
+class AdaptorInternalServices;
+class EglFactoryInterface;
+
+/**
+ * Helper class for EGL, surface, pre & post rendering
+ */
+class RenderHelper
+{
+public:
+
+ /**
+ * Create a RenderHelper.
+ * @param[in] adaptorInterfaces base adaptor interface
+ */
+ RenderHelper( AdaptorInternalServices& adaptorInterfaces );
+
+ /**
+ * Non-virtual Destructor
+ */
+ ~RenderHelper();
+
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // Called on the Event Thread
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+
+ /**
+ * Sets up all render related objects to start rendering.
+ */
+ void Start();
+
+ /**
+ * Sets up all render related objects to stop rendering.
+ */
+ void Stop();
+
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // Called on the Rendering Thread
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+
+ /**
+ * Consumes any pending events to avoid memory leaks
+ *
+ * @note Called from rendering thread
+ */
+ void ConsumeEvents();
+
+ /**
+ * Initializes EGL.
+ *
+ * @note Called from rendering thread
+ */
+ void InitializeEgl();
+
+ /**
+ * Replaces the rendering surface
+ *
+ * Used for replacing pixmaps due to resizing
+ * @param newSurface to use
+ *
+ * @note Called from render thread
+ */
+ void ReplaceSurface( RenderSurface* newSurface );
+
+ /**
+ * Shuts down EGL.
+ *
+ * @note Called from render thread
+ */
+ void ShutdownEgl();
+
+ /**
+ * Called before core renders the scene
+ *
+ * @return true if successful and Core::Render should be called.
+ *
+ * @note Called from render thread
+ */
+ bool PreRender();
+
+ /**
+ * Called after core has rendered the scene
+ *
+ * @note Called from render thread
+ */
+ void PostRender();
+
+private:
+
+ // Undefined
+ RenderHelper( const RenderHelper& RenderHelper );
+
+ // Undefined
+ RenderHelper& operator=( const RenderHelper& RenderHelper );
+
+private: // Data
+
+ Integration::GlAbstraction& mGLES; ///< GL abstraction reference
+ EglFactoryInterface* mEglFactory; ///< Factory class to create EGL implementation
+ EglInterface* mEGL; ///< Interface to EGL implementation
+ RenderSurface* mSurface; ///< Current surface
+ Dali::DisplayConnection* mDisplayConnection; ///< Display connection
+ bool mSurfaceReplaced; ///< True when new surface has been initialized.
+};
+
+} // namespace Adaptor
+
+} // namespace Internal
+
+} // namespace Dali
+
+#endif // __DALI_INTERNAL_RENDER_HELPER_H__
--- /dev/null
+/*
+ * Copyright (c) 2015 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 "render-request.h"
+
+// EXTERNAL INCLUDES
+
+// INTERNAL INCLUDES
+
+namespace Dali
+{
+
+namespace Internal
+{
+
+namespace Adaptor
+{
+
+namespace
+{
+}
+
+RenderRequest::RenderRequest( RenderRequest::Request type )
+: mRequestType( type )
+{
+}
+
+RenderRequest::Request RenderRequest::GetType()
+{
+ return mRequestType;
+}
+
+ReplaceSurfaceRequest::ReplaceSurfaceRequest()
+: RenderRequest( RenderRequest::REPLACE_SURFACE ),
+ mNewSurface( NULL ),
+ mReplaceCompleted( false )
+{
+}
+
+void ReplaceSurfaceRequest::SetSurface( RenderSurface* newSurface )
+{
+ mNewSurface = newSurface;
+}
+
+RenderSurface* ReplaceSurfaceRequest::GetSurface()
+{
+ return mNewSurface;
+}
+
+void ReplaceSurfaceRequest::ReplaceCompleted()
+{
+ mReplaceCompleted = true;
+}
+
+bool ReplaceSurfaceRequest::GetReplaceCompleted()
+{
+ return mReplaceCompleted != 0u;
+}
+
+} // namespace Adaptor
+
+} // namespace Internal
+
+} // namespace Dali
--- /dev/null
+#ifndef __DALI_INTERNAL_RENDER_REQUEST_H__
+#define __DALI_INTERNAL_RENDER_REQUEST_H__
+
+/*
+ * Copyright (c) 2015 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.
+ *
+ */
+
+// EXTERNAL INCLUDES
+
+// INTERNAL INCLUDES
+#include <egl-interface.h>
+#include <render-surface.h> // needed for Dali::RenderSurface
+
+namespace Dali
+{
+
+class RenderSurface;
+class DisplayConnection;
+
+namespace Internal
+{
+namespace Adaptor
+{
+
+class RenderRequest
+{
+public:
+ enum Request
+ {
+ REPLACE_SURFACE, // Request to replace surface
+ };
+
+ /**
+ * Constructor.
+ * @param[in] type The type of the request
+ */
+ RenderRequest( Request type );
+
+ /**
+ * @return the type of the request
+ */
+ Request GetType();
+
+private:
+ Request mRequestType;
+};
+
+class ReplaceSurfaceRequest : public RenderRequest
+{
+public:
+
+ /**
+ * Constructor
+ */
+ ReplaceSurfaceRequest();
+
+ /**
+ * Set the new surface
+ * @param[in] newSurface The new surface to use
+ */
+ void SetSurface(RenderSurface* newSurface);
+
+ /**
+ * @return the new surface
+ */
+ RenderSurface* GetSurface();
+
+ /**
+ * Called when the request has been completed to set the result.
+ */
+ void ReplaceCompleted();
+
+ /**
+ * @return true if the replace has completed.
+ */
+ bool GetReplaceCompleted();
+
+private:
+ RenderSurface* mNewSurface; ///< The new surface to use.
+ unsigned int mReplaceCompleted; ///< Set to true when the replace has completed.
+};
+
+} // namespace Adaptor
+
+} // namespace Internal
+
+} // namespace Dali
+
+#endif // __DALI_INTERNAL_RENDER_REQUEST_H__
#include <base/interfaces/adaptor-internal-services.h>
#include <base/thread-synchronization.h>
#include <base/environment-options.h>
-#include <base/display-connection.h>
namespace Dali
{
#endif
}
-RenderRequest::RenderRequest(RenderRequest::Request type)
-: mRequestType(type)
-{
-}
-
-RenderRequest::Request RenderRequest::GetType()
-{
- return mRequestType;
-}
-
-ReplaceSurfaceRequest::ReplaceSurfaceRequest()
-: RenderRequest(RenderRequest::REPLACE_SURFACE),
- mNewSurface( NULL ),
- mReplaceCompleted(false)
-{
-}
-
-void ReplaceSurfaceRequest::SetSurface(RenderSurface* newSurface)
-{
- mNewSurface = newSurface;
-}
-
-RenderSurface* ReplaceSurfaceRequest::GetSurface()
-{
- return mNewSurface;
-}
-
-void ReplaceSurfaceRequest::ReplaceCompleted()
-{
- mReplaceCompleted = true;
-}
-
-bool ReplaceSurfaceRequest::GetReplaceCompleted()
-{
- return mReplaceCompleted != 0u;
-}
-
-
RenderThread::RenderThread( ThreadSynchronization& sync,
AdaptorInternalServices& adaptorInterfaces,
const EnvironmentOptions& environmentOptions )
: mThreadSynchronization( sync ),
mCore( adaptorInterfaces.GetCore() ),
- mGLES( adaptorInterfaces.GetGlesInterface() ),
- mEglFactory( &adaptorInterfaces.GetEGLFactoryInterface()),
- mEGL( NULL ),
mThread( NULL ),
mEnvironmentOptions( environmentOptions ),
- mSurfaceReplaced(false)
+ mRenderHelper( adaptorInterfaces )
{
- // set the initial values before render thread starts
- mSurface = adaptorInterfaces.GetRenderSurfaceInterface();
-
- mDisplayConnection = Dali::DisplayConnection::New();
}
RenderThread::~RenderThread()
{
- if (mDisplayConnection)
- {
- delete mDisplayConnection;
- mDisplayConnection = NULL;
- }
-
- DALI_ASSERT_ALWAYS( mThread == NULL && "RenderThread is still alive");
- mEglFactory->Destroy();
}
void RenderThread::Start()
{
DALI_LOG_INFO( gRenderLogFilter, Debug::Verbose, "RenderThread::Start()\n");
- // initialise GL and kick off render thread
- DALI_ASSERT_ALWAYS( !mEGL && "Egl already initialized" );
-
// create the render thread, initially we are rendering
mThread = new pthread_t();
int error = pthread_create( mThread, NULL, InternalThreadEntryFunc, this );
DALI_ASSERT_ALWAYS( !error && "Return code from pthread_create() in RenderThread" );
- if( mSurface )
- {
- mSurface->StartRender();
- }
+ mRenderHelper.Start();
}
void RenderThread::Stop()
{
DALI_LOG_INFO( gRenderLogFilter, Debug::Verbose, "RenderThread::Stop()\n");
- if( mSurface )
- {
- // Tell surface we have stopped rendering
- mSurface->StopRender();
-
- // The surface will be destroyed soon; this pointer will become invalid
- mSurface = NULL;
- }
+ mRenderHelper.Stop();
// shutdown the render thread and destroy the opengl context
if( mThread )
// Install a function for logging
mEnvironmentOptions.InstallLogFunction();
- InitializeEgl();
+ mRenderHelper.InitializeEgl();
+
+ // tell core it has a context
+ mCore.ContextCreated();
Dali::Integration::RenderStatus renderStatus;
RenderRequest* request = NULL;
// Consume any pending events to avoid memory leaks
DALI_LOG_INFO( gRenderLogFilter, Debug::Verbose, "RenderThread::Run. 2 - ConsumeEvents\n");
- mDisplayConnection->ConsumeEvents();
+ mRenderHelper.ConsumeEvents();
// Check if we've got a request from the main thread (e.g. replace surface)
if( request )
else
{
// No request to process so we render
- if( PreRender() ) // Returns false if no surface onto which to render
+ if( mRenderHelper.PreRender() ) // Returns false if no surface onto which to render
{
// Render
DALI_LOG_INFO( gRenderLogFilter, Debug::Verbose, "RenderThread::Run. 3 - Core.Render()\n");
if ( renderStatus.HasRendered() )
{
DALI_LOG_INFO( gRenderLogFilter, Debug::Verbose, "RenderThread::Run. 4 - PostRender()\n");
- PostRender();
+ mRenderHelper.PostRender();
}
}
}
request = NULL; // Clear the request if it was set, no need to release memory
}
- // Shut down EGL
- ShutdownEgl();
+ // Inform core of context destruction & shutdown EGL
+ mCore.ContextDestroyed();
+ mRenderHelper.ShutdownEgl();
// Uninstall the logging function
mEnvironmentOptions.UnInstallLogFunction();
return true;
}
-void RenderThread::InitializeEgl()
-{
- mEGL = mEglFactory->Create();
-
- DALI_ASSERT_ALWAYS( mSurface && "NULL surface" );
-
- // initialize egl & OpenGL
- mDisplayConnection->InitializeEgl( *mEGL );
- mSurface->InitializeEgl( *mEGL );
-
- // create the OpenGL context
- mEGL->CreateContext();
-
- // create the OpenGL surface
- mSurface->CreateEglSurface(*mEGL);
-
- // Make it current
- mEGL->MakeContextCurrent();
-
- // set the initial sync mode
-
- // tell core it has a context
- mCore.ContextCreated();
-
-}
-
void RenderThread::ProcessRequest( RenderRequest* request )
{
if( request != NULL )
{
// change the surface
ReplaceSurfaceRequest* replaceSurfaceRequest = static_cast<ReplaceSurfaceRequest*>(request);
- ReplaceSurface( replaceSurfaceRequest->GetSurface() );
+ mRenderHelper.ReplaceSurface( replaceSurfaceRequest->GetSurface() );
replaceSurfaceRequest->ReplaceCompleted();
mThreadSynchronization.RenderInformSurfaceReplaced();
break;
}
}
-void RenderThread::ReplaceSurface( RenderSurface* newSurface )
-{
- // This is designed for replacing pixmap surfaces, but should work for window as well
- // we need to delete the egl surface and renderable (pixmap / window)
- // Then create a new pixmap/window and new egl surface
- // If the new surface has a different display connection, then the context will be lost
- DALI_ASSERT_ALWAYS(newSurface && "NULL surface");
-
- mDisplayConnection->InitializeEgl(*mEGL);
-
- newSurface->ReplaceEGLSurface(*mEGL);
-
- // use the new surface from now on
- mSurface = newSurface;
- mSurfaceReplaced = true;
-}
-
-void RenderThread::ShutdownEgl()
-{
- // inform core of context destruction
- mCore.ContextDestroyed();
-
- if( mSurface )
- {
- // give a chance to destroy the OpenGL surface that created externally
- mSurface->DestroyEglSurface( *mEGL );
- }
-
- // delete the GL context / egl surface
- mEGL->TerminateGles();
-}
-
-bool RenderThread::PreRender()
-{
- bool success( false );
- if( mSurface )
- {
- success = mSurface->PreRender( *mEGL, mGLES );
- }
-
- if( success )
- {
- mGLES.PreRender();
- }
- return success;
-}
-
-void RenderThread::PostRender()
-{
- // Inform the gl implementation that rendering has finished before informing the surface
- mGLES.PostRender();
-
- if( mSurface )
- {
- // Inform the surface that rendering this frame has finished.
- mSurface->PostRender( *mEGL, mGLES, mDisplayConnection, mSurfaceReplaced );
- }
- mSurfaceReplaced = false;
-}
-
} // namespace Adaptor
} // namespace Internal
#include <pthread.h>
// INTERNAL INCLUDES
+#include <base/render-helper.h>
+#include <base/render-request.h>
#include <egl-interface.h>
#include <render-surface.h> // needed for Dali::RenderSurface
{
class RenderSurface;
-class DisplayConnection;
namespace Integration
{
-class GlAbstraction;
class Core;
}
class AdaptorInternalServices;
class ThreadSynchronization;
-class EglFactoryInterface;
class EnvironmentOptions;
-class RenderRequest
-{
-public:
- enum Request
- {
- REPLACE_SURFACE, // Request to replace surface
- };
-
- /**
- * Constructor.
- * @param[in] type The type of the request
- */
- RenderRequest( Request type );
-
- /**
- * @return the type of the request
- */
- Request GetType();
-
-private:
- Request mRequestType;
-};
-
-class ReplaceSurfaceRequest : public RenderRequest
-{
-public:
-
- /**
- * Constructor
- */
- ReplaceSurfaceRequest();
-
- /**
- * Set the new surface
- * @param[in] newSurface The new surface to use
- */
- void SetSurface(RenderSurface* newSurface);
-
- /**
- * @return the new surface
- */
- RenderSurface* GetSurface();
-
- /**
- * Called when the request has been completed to set the result.
- */
- void ReplaceCompleted();
-
- /**
- * @return true if the replace has completed.
- */
- bool GetReplaceCompleted();
-
-private:
- RenderSurface* mNewSurface; ///< The new surface to use.
- unsigned int mReplaceCompleted; ///< Set to true when the replace has completed.
-};
-
-
/**
* The render-thread is responsible for calling Core::Render() after each update.
*/
bool Run();
/**
- * Initializes EGL.
- * Called from render thread
- */
- void InitializeEgl();
-
- /**
* Check if main thread made any requests, e.g. ReplaceSurface
* Called from render thread
*/
void ProcessRequest( RenderRequest* request );
/**
- * Replaces the rendering surface
- * Used for replacing pixmaps due to resizing
- * Called from render thread
- * @param newSurface to use
- */
- void ReplaceSurface( RenderSurface* newSurface );
-
- /**
- * Shuts down EGL.
- * Called from render thread
- */
- void ShutdownEgl();
-
- /**
- * Called before core renders the scene
- * Called from render thread
- * @return true if successful and Core::Render should be called.
- */
- bool PreRender();
-
- /**
- * Called after core has rendered the scene
- * Called from render thread
- */
- void PostRender();
-
- /**
* Helper for the thread calling the entry function.
* @param[in] This A pointer to the current RenderThread object
*/
ThreadSynchronization& mThreadSynchronization; ///< Used to synchronize the all threads
Dali::Integration::Core& mCore; ///< Dali core reference
- Integration::GlAbstraction& mGLES; ///< GL abstraction reference
- EglFactoryInterface* mEglFactory; ///< Factory class to create EGL implementation
- EglInterface* mEGL; ///< Interface to EGL implementation
pthread_t* mThread; ///< render thread
- RenderSurface* mSurface; ///< Current surface
- Dali::DisplayConnection* mDisplayConnection; ///< Display connection
const EnvironmentOptions& mEnvironmentOptions; ///< Environment options
- bool mSurfaceReplaced; ///< True when new surface has been initialzed.
+ RenderHelper mRenderHelper; ///< Helper class for EGL, pre & post rendering
};
} // namespace Adaptor
#include <base/interfaces/performance-interface.h>
#include <trigger-event-interface.h>
#include <base/frame-time.h>
-#include <base/render-thread.h>
+#include <base/render-request.h>
namespace Dali
{