2 * Copyright (c) 2016 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 <pepper-dali/internal/output-impl.h>
22 #include <pepper-dali/internal/compositor-impl.h>
25 #include <dali/integration-api/adaptors/adaptor.h>
26 #include <dali/devel-api/adaptor-framework/render-surface.h>
27 #include <dali/integration-api/debug.h>
41 #if defined(DEBUG_ENABLED)
42 Integration::Log::Filter* gPepperOutputLogging = Integration::Log::Filter::New( Debug::Verbose, false, "LOG_PEPPER_OUTPUT" );
45 static const struct pepper_output_backend outputInterface =
49 Output::OnGetSubpixelOrder,
50 Output::OnGetMakerName,
51 Output::OnGetModelName,
53 Output::OnGetModeCount,
57 Output::OnAssignPlanes,
58 Output::OnStartRepaintLoop,
60 Output::OnAttachSurface,
61 Output::OnFlushSurface
64 } // unnamed namespace
66 OutputPtr Output::New( Pepper::Compositor compositor, Application application, Pepper::Input input )
68 OutputPtr impl = new Output();
70 // Second-phase init of the implementation
71 impl->Initialize( compositor, application, input );
79 mPrimaryPlane( NULL ),
80 mRepaintRequest( false )
88 void Output::Initialize( Pepper::Compositor& compositor, Application application, Pepper::Input input )
90 mCompositor = compositor;
93 RenderSurface& surface = Adaptor::Get().GetSurface();
94 PositionSize positionSize = surface.GetPositionSize();
96 mSize.width = positionSize.width;
97 mSize.height = positionSize.height;
99 mOutput = pepper_compositor_add_output( static_cast< pepper_compositor_t* >( Pepper::GetImplementation( compositor ).GetCompositorHandle() ), &outputInterface, "dali", this, WL_OUTPUT_TRANSFORM_NORMAL, 1 );
102 DALI_LOG_INFO( gPepperOutputLogging, Debug::General, "Output::Initialize: pepper_compositor_add_output is failed\n" );
106 mPrimaryPlane = pepper_output_add_plane( mOutput, NULL );
109 DALI_LOG_INFO( gPepperOutputLogging, Debug::General, "Output::Initialize: pepper_output_add_plane is failed\n" );
110 pepper_output_destroy( mOutput );
114 application.ResizeSignal().Connect( this, &Output::OnResize );
116 // Set the thread-synchronization interface on the render-surface
117 surface.SetThreadSynchronization( *this );
119 DALI_LOG_INFO( gPepperOutputLogging, Debug::Verbose, "Output::Initialize: success [width = %.2f height = %.2f]\n", mSize.width, mSize.height );
122 void Output::OnDestroy( void* data )
124 Output* output = static_cast< Output* >( data );
126 if( output->mPrimaryPlane )
128 pepper_plane_destroy( output->mPrimaryPlane );
129 output->mPrimaryPlane = NULL;
133 int32_t Output::OnGetSubpixelOrder( void* data )
135 return WL_OUTPUT_SUBPIXEL_UNKNOWN;
138 const char* Output::OnGetMakerName( void* data )
140 return "PePPer DALi";
143 const char* Output::OnGetModelName( void* data )
145 return "PePPer DALi";
148 int Output::OnGetModeCount( void* data )
153 void Output::OnGetMode( void* data, int index, pepper_output_mode_t* mode )
155 Output* output = static_cast< Output* >( data );
159 DALI_LOG_INFO( gPepperOutputLogging, Debug::General, "Output::OnGetMode: wrong index [%d]\n", index );
165 mode->flags = WL_OUTPUT_MODE_CURRENT | WL_OUTPUT_MODE_PREFERRED;
166 mode->w = (int32_t)output->mSize.width;
167 mode->h = (int32_t)output->mSize.height;
168 mode->refresh = 60000;
172 pepper_bool_t Output::OnSetMode( void* data, const pepper_output_mode_t* mode )
177 void Output::OnAssignPlanes( void* data, const pepper_list_t* viewList )
179 Output* output = static_cast< Output* >( data );
182 pepper_list_for_each_list( list, viewList )
184 pepper_view_t* view = static_cast< pepper_view_t* >( list->item );
185 pepper_view_assign_plane( view, output->mOutput, output->mPrimaryPlane );
189 void Output::OnStartRepaintLoop( void* data )
191 Output* output = static_cast< Output* >( data );
194 DALI_LOG_INFO( gPepperOutputLogging, Debug::Verbose, "Output::OnStartRepaintLoop\n" );
196 pepper_compositor_get_time( static_cast< pepper_compositor_t* >( Pepper::GetImplementation( output->mCompositor ).GetCompositorHandle() ), &ts );
197 pepper_output_finish_frame( output->mOutput, &ts );
200 void Output::OnRepaint( void* data, const pepper_list_t* planeList )
202 Output* output = static_cast< Output* >( data );
204 DALI_LOG_INFO( gPepperOutputLogging, Debug::Verbose, "Output::OnRepaint\n" );
206 output->mRepaintRequest = true;
209 if( !output->mRenderFinishTimer )
211 output->mRenderFinishTimer= Timer::New(1);
212 output->mRenderFinishTimer.TickSignal().Connect( output, &Output::OnRenderFinishTimerTick );
215 output->mRenderFinishTimer.Start();
218 void Output::OnAttachSurface( void* data, pepper_surface_t* surface, int* width, int* height )
220 Output* output = static_cast< Output* >( data );
221 Pepper::Object object;
223 DALI_LOG_INFO( gPepperOutputLogging, Debug::Verbose, "Output::OnAttachSurface: surface = %p\n", surface );
225 long index = reinterpret_cast< long >( pepper_object_get_user_data( (pepper_object_t*)surface, output ) );
228 object = Pepper::Object::New( surface, output->mInput );
230 object.ObjectViewAddedSignal().Connect( output, &Output::OnObjectViewAdded );
231 object.ObjectViewDeletedSignal().Connect( output, &Output::OnObjectViewDeleted );
233 index = output->mObjectList.size() + 1;
234 output->mObjectList.push_back( object );
236 pepper_object_set_user_data( (pepper_object_t*)surface, output, reinterpret_cast< void* >( index ), NULL );
238 DALI_LOG_INFO( gPepperOutputLogging, Debug::Verbose, "Output::OnAttachSurface: object index = %d\n", index );
242 object = output->mObjectList[index - 1];
245 if( !object.AttchBuffer( width, height ) )
254 pepper_compositor_get_time( static_cast< pepper_compositor_t* >( Pepper::GetImplementation( output->mCompositor ).GetCompositorHandle() ), &ts );
255 pepper_output_finish_frame( output->mOutput, &ts );
258 void Output::OnFlushSurface( void* data, pepper_surface_t* surface, pepper_bool_t* keepBuffer )
262 Pepper::Output::OutputSignalType& Output::ObjectViewAddedSignal()
264 return mObjectViewAddedSignal;
267 Pepper::Output::OutputSignalType& Output::ObjectViewDeletedSignal()
269 return mObjectViewDeletedSignal;
272 void Output::OnResize( Application& application )
274 RenderSurface& surface = Adaptor::Get().GetSurface();
275 PositionSize positionSize = surface.GetPositionSize();
277 mSize.width = positionSize.width;
278 mSize.height = positionSize.height;
280 pepper_output_update_mode( mOutput );
283 void Output::OnObjectViewAdded( Pepper::Object object, Pepper::ObjectView objectView )
285 Pepper::Output handle( this );
286 mObjectViewAddedSignal.Emit( handle, objectView );
289 void Output::OnObjectViewDeleted( Pepper::Object object, Pepper::ObjectView objectView )
291 Pepper::Output handle( this );
292 mObjectViewDeletedSignal.Emit( handle, objectView );
294 for ( std::vector< Pepper::Object >::iterator iter = mObjectList.begin(); mObjectList.end() != iter; ++iter )
296 if( *iter == object )
298 mObjectList.erase( iter );
304 void Output::PostRenderComplete()
306 if( mRepaintRequest )
310 DALI_LOG_INFO( gPepperOutputLogging, Debug::Verbose, "Output::PostRenderComplete" );
312 pepper_compositor_get_time( static_cast< pepper_compositor_t* >( Pepper::GetImplementation( mCompositor ).GetCompositorHandle() ), &ts );
313 pepper_output_finish_frame( mOutput, &ts );
315 mRepaintRequest = false;
319 void Output::PostRenderStarted()
324 void Output::PostRenderWaitForCompletion()
330 bool Output::OnRenderFinishTimerTick()
334 DALI_LOG_INFO( gPepperOutputLogging, Debug::Verbose, "Output::OnRenderFinishTimerTick\n" );
336 pepper_compositor_get_time( static_cast< pepper_compositor_t* >( Pepper::GetImplementation( mCompositor ).GetCompositorHandle() ), &ts );
337 pepper_output_finish_frame( mOutput, &ts );
342 } // namespace Internal
344 } // namespace Pepper