2 * Copyright (c) 2015 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include "render-thread.h"
22 #include <dali/integration-api/debug.h>
25 #include <base/interfaces/adaptor-internal-services.h>
26 #include <base/separate-update-render/thread-synchronization.h>
27 #include <base/environment-options.h>
40 #if defined(DEBUG_ENABLED)
41 Integration::Log::Filter* gRenderLogFilter = Integration::Log::Filter::New(Debug::NoLogging, false, "LOG_RENDER_THREAD");
45 RenderThread::RenderThread( ThreadSynchronization& sync,
46 AdaptorInternalServices& adaptorInterfaces,
47 const EnvironmentOptions& environmentOptions )
48 : mThreadSynchronization( sync ),
49 mCore( adaptorInterfaces.GetCore() ),
51 mEnvironmentOptions( environmentOptions ),
52 mRenderHelper( adaptorInterfaces )
56 RenderThread::~RenderThread()
60 void RenderThread::Start()
62 DALI_LOG_INFO( gRenderLogFilter, Debug::Verbose, "RenderThread::Start()\n");
64 // create the render thread, initially we are rendering
65 mThread = new pthread_t();
66 int error = pthread_create( mThread, NULL, InternalThreadEntryFunc, this );
67 DALI_ASSERT_ALWAYS( !error && "Return code from pthread_create() in RenderThread" );
69 mRenderHelper.Start();
72 void RenderThread::Stop()
74 DALI_LOG_INFO( gRenderLogFilter, Debug::Verbose, "RenderThread::Stop()\n");
78 // shutdown the render thread and destroy the opengl context
81 // wait for the thread to finish
82 pthread_join(*mThread, NULL);
89 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
90 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
91 // The following methods are all executed inside render thread !!!
92 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
93 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
95 bool RenderThread::Run()
97 DALI_LOG_INFO( gRenderLogFilter, Debug::Verbose, "RenderThread::Run\n");
99 // Install a function for logging
100 mEnvironmentOptions.InstallLogFunction();
102 mRenderHelper.InitializeEgl();
104 // tell core it has a context
105 mCore.ContextCreated();
107 Dali::Integration::RenderStatus renderStatus;
108 RenderRequest* request = NULL;
110 // Render loop, we stay inside here when rendering
111 while( mThreadSynchronization.RenderReady( request ) )
113 DALI_LOG_INFO( gRenderLogFilter, Debug::Verbose, "RenderThread::Run. 1 - RenderReady\n");
115 // Consume any pending events to avoid memory leaks
116 DALI_LOG_INFO( gRenderLogFilter, Debug::Verbose, "RenderThread::Run. 2 - ConsumeEvents\n");
117 mRenderHelper.ConsumeEvents();
119 // Check if we've got a request from the main thread (e.g. replace surface)
122 // Process the request, we should NOT render when we have a request
123 DALI_LOG_INFO( gRenderLogFilter, Debug::Verbose, "RenderThread::Run. 3 - Process requests\n");
124 ProcessRequest( request );
128 // No request to process so we render
129 if( mRenderHelper.PreRender() ) // Returns false if no surface onto which to render
132 DALI_LOG_INFO( gRenderLogFilter, Debug::Verbose, "RenderThread::Run. 3 - Core.Render()\n");
134 mThreadSynchronization.AddPerformanceMarker( PerformanceInterface::RENDER_START );
135 mCore.Render( renderStatus );
136 mThreadSynchronization.AddPerformanceMarker( PerformanceInterface::RENDER_END );
138 // Decrement the count of how far update is ahead of render
139 mThreadSynchronization.RenderFinished();
141 // Perform any post-render operations
142 if( renderStatus.NeedsPostRender() )
144 DALI_LOG_INFO( gRenderLogFilter, Debug::Verbose, "RenderThread::Run. 4 - PostRender()\n");
145 mRenderHelper.PostRender();
150 request = NULL; // Clear the request if it was set, no need to release memory
153 // Inform core of context destruction & shutdown EGL
154 mCore.ContextDestroyed();
155 mRenderHelper.ShutdownEgl();
157 // Uninstall the logging function
158 mEnvironmentOptions.UnInstallLogFunction();
163 void RenderThread::ProcessRequest( RenderRequest* request )
165 if( request != NULL )
167 switch(request->GetType())
169 case RenderRequest::REPLACE_SURFACE:
171 // change the surface
172 ReplaceSurfaceRequest* replaceSurfaceRequest = static_cast<ReplaceSurfaceRequest*>(request);
173 mRenderHelper.ReplaceSurface( replaceSurfaceRequest->GetSurface() );
174 replaceSurfaceRequest->ReplaceCompleted();
175 mThreadSynchronization.RenderInformSurfaceReplaced();
182 } // namespace Adaptor
184 } // namespace Internal