[dali_1.4.26] Merge branch 'devel/master'
[platform/core/uifw/dali-toolkit.git] / plugins / dali-script-v8 / src / render-tasks / render-task-api.cpp
1 /*
2  * Copyright (c) 2015 Samsung Electronics Co., Ltd.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  *
16  */
17
18
19 // CLASS HEADER
20 #include "render-task-api.h"
21
22 // INTERNAL INCLUDES
23 #include <v8-utils.h>
24 #include <render-tasks/render-task-wrapper.h>
25 #include <image/image-wrapper.h>
26 #include <actors/actor-wrapper.h>
27 #include <dali/public-api/render-tasks/render-task.h>
28 #include <dali/public-api/actors/camera-actor.h>
29
30
31 namespace Dali
32 {
33
34 namespace V8Plugin
35 {
36
37 namespace // un named namespace
38 {
39
40
41 RenderTask GetRenderTask( v8::Isolate* isolate, const v8::FunctionCallbackInfo< v8::Value >& args )
42 {
43   v8::HandleScope handleScope( isolate );
44
45   v8::Local<v8::Object> object = args.This();
46   v8::Local<v8::External> field = v8::Local<v8::External>::Cast( object->GetInternalField(0) );
47   void* ptr = field->Value();
48
49   RenderTaskWrapper* wrapper = static_cast< RenderTaskWrapper *>(ptr);
50   return wrapper->GetRenderTask();
51 }
52
53 }
54
55 /**
56  * Set the actors to be rendered
57  * @method setSourceActor
58  * @for RenderTask
59  * @param {Object} actor This actor and its children will be rendered.
60  */
61 void RenderTaskApi::SetSourceActor( const v8::FunctionCallbackInfo< v8::Value >& args )
62 {
63   v8::Isolate* isolate = args.GetIsolate();
64   v8::HandleScope handleScope( isolate );
65   RenderTask renderTask = GetRenderTask( isolate, args );
66   bool found( false );
67   Actor sourceActor = V8Utils::GetActorParameter( PARAMETER_0, found, isolate, args );
68
69   if( found )
70   {
71     renderTask.SetSourceActor( sourceActor );
72   }
73   else
74   {
75     DALI_SCRIPT_EXCEPTION( isolate, "source actor not found" );
76   }
77
78 }
79 /**
80  * Get the actor to be rendered
81  * @method getSourceActor
82  * @for RenderTask
83  * @param {Object} actor source actor
84  */
85 void RenderTaskApi::GetSourceActor(const v8::FunctionCallbackInfo< v8::Value >& args )
86 {
87   v8::Isolate* isolate = args.GetIsolate();
88   v8::HandleScope handleScope( isolate );
89   RenderTask renderTask = GetRenderTask( isolate, args );
90
91   Actor source = renderTask.GetSourceActor();
92
93   v8::Handle < v8::Object > wrappedActor = ActorWrapper::WrapActor( isolate, source );
94   args.GetReturnValue().Set( wrappedActor );
95 }
96
97 /**
98  * Set whether the RenderTask has exclusive access to the source actors; the default is false.
99  * @method setExclusive
100  * @for RenderTask
101  * @param {Boolean} exclusive True if the source actors will only be rendered by this render-task.
102  */
103 void RenderTaskApi::SetExclusive( const v8::FunctionCallbackInfo< v8::Value >& args )
104 {
105   v8::Isolate* isolate = args.GetIsolate();
106   v8::HandleScope handleScope( isolate );
107   RenderTask renderTask = GetRenderTask( isolate, args );
108
109   bool found( false );
110   bool exclusive = V8Utils::GetBooleanParameter( PARAMETER_0, found, isolate, args );
111   if( !found )
112   {
113     DALI_SCRIPT_EXCEPTION( isolate, "boolean parameter missing" );
114     return;
115   }
116   renderTask.SetExclusive( exclusive );
117
118 }
119
120 /**
121  * Query whether the RenderTask has exclusive access to the source actors.
122  * @method isExclusive
123  * @for RenderTask
124  * @return {Boolean} exclusive True if the source actors will only be rendered by this render-task.
125  */
126 void RenderTaskApi::IsExclusive( const v8::FunctionCallbackInfo< v8::Value >& args )
127 {
128   v8::Isolate* isolate = args.GetIsolate();
129   v8::HandleScope handleScope( isolate );
130   RenderTask renderTask = GetRenderTask( isolate, args );
131
132   args.GetReturnValue().Set( v8::Boolean::New( isolate, renderTask.IsExclusive() ) );
133
134 }
135
136 /**
137  * Set whether the render-task should be considered for input handling; the default is true.
138  *
139  * The task used for input handling will be last task in the RenderTaskList which has input enabled,
140  * and has a valid source & camera actor.
141  * A RenderTask targetting a frame-buffer can still be hit-tested, provided that the screen->frame-buffer
142  * coordinate conversion is successful; see also SetScreenToFrameBufferFunction().
143  * @method setInputEnabled
144  * @for RenderTask
145  * @param {Boolean} enabled True if the render-task should be considered for input handling.
146  */
147 void RenderTaskApi::SetInputEnabled( const v8::FunctionCallbackInfo< v8::Value >& args )
148 {
149   v8::Isolate* isolate = args.GetIsolate();
150   v8::HandleScope handleScope( isolate );
151   RenderTask renderTask = GetRenderTask( isolate, args );
152
153   bool found( false );
154   bool inputEnabled = V8Utils::GetBooleanParameter( PARAMETER_0, found, isolate, args );
155   if( !found )
156   {
157     DALI_SCRIPT_EXCEPTION( isolate, "boolean parameter missing" );
158     return;
159   }
160   renderTask.SetInputEnabled( inputEnabled );
161
162 }
163
164 /**
165  * Query whether the render-task should be considered for input handling.
166  * @method getInputEnabled
167  * @for RenderTask
168  * @return {Boolean} enabled True if the render-task should be considered for input handling.
169  */
170 void RenderTaskApi::GetInputEnabled( const v8::FunctionCallbackInfo< v8::Value >& args )
171 {
172   v8::Isolate* isolate = args.GetIsolate();
173   v8::HandleScope handleScope( isolate );
174   RenderTask renderTask = GetRenderTask( isolate, args );
175
176   args.GetReturnValue().Set( v8::Boolean::New( isolate, renderTask.GetInputEnabled() ) );
177
178
179 }
180
181 /**
182  * Set the actor from which the scene is viewed.
183  * @method setCameraActor
184  * @for RenderTask
185  * @param {Object} cameraActor The scene is viewed from the perspective of this actor.
186  */
187 void RenderTaskApi::SetCameraActor( const v8::FunctionCallbackInfo< v8::Value >& args )
188 {
189   v8::Isolate* isolate = args.GetIsolate();
190   v8::HandleScope handleScope( isolate );
191   RenderTask renderTask = GetRenderTask( isolate, args );
192   bool found (false );
193   CameraActor cameraActor;
194   Actor actor =  V8Utils::GetActorParameter( PARAMETER_0, found, isolate, args );
195   if( found )
196   {
197     cameraActor = CameraActor::DownCast( actor );
198   }
199
200   if( cameraActor )
201   {
202      renderTask.SetCameraActor( cameraActor );
203   }
204   else
205   {
206     DALI_SCRIPT_EXCEPTION( isolate, "source actor not found" );
207   }
208
209 }
210
211 /**
212  * Retrieve the actor from which the scene is viewed..
213  * @method getCameraActor
214  * @for RenderTask
215  * @return {Object} cameraActor The scene is viewed from the perspective of this actor.
216  */
217 void RenderTaskApi::GetCameraActor( const v8::FunctionCallbackInfo< v8::Value >& args )
218 {
219   v8::Isolate* isolate = args.GetIsolate();
220   v8::HandleScope handleScope( isolate );
221   RenderTask renderTask = GetRenderTask( isolate, args );
222
223   Actor cameraActor = renderTask.GetSourceActor();
224
225   v8::Handle < v8::Object > wrappedActor = ActorWrapper::WrapActor( isolate, cameraActor );
226   args.GetReturnValue().Set( wrappedActor );
227
228 }
229
230 /**
231  * Set the frame-buffer used as a render target.
232  * @method setTargetFrameBuffer
233  * @for RenderTask
234  * @param {Object}  frameBuffer A valid frame-buffer handle to enable off-screen rendering, or an uninitialized handle to disable.
235  */
236 void RenderTaskApi::SetTargetFrameBuffer(const v8::FunctionCallbackInfo< v8::Value >& args )
237 {
238   v8::Isolate* isolate = args.GetIsolate();
239   v8::HandleScope handleScope( isolate );
240   RenderTask renderTask = GetRenderTask( isolate, args );
241
242   bool found( false );
243   // @TODO Test this, may need to implement a Framebuffer image.?
244   Image image = V8Utils::GetImageParameter( PARAMETER_0, found, isolate, args );
245   if( !found )
246   {
247      DALI_SCRIPT_EXCEPTION( isolate, "bad parameters" );
248      return;
249   }
250
251   FrameBufferImage frameBufferImage = FrameBufferImage::DownCast(image);
252
253   renderTask.SetTargetFrameBuffer( frameBufferImage );
254
255 }
256
257
258 /**
259  * Get the frame-buffer used as a render target.
260  * @method getTargetFrameBuffer
261  * @for RenderTask
262  * @return {Object}  frameBuffer A valid frame-buffer handle to enable off-screen rendering, or an uninitialized handle to disable.
263  */
264 void RenderTaskApi::GetTargetFrameBuffer( const v8::FunctionCallbackInfo< v8::Value >& args )
265 {
266   v8::Isolate* isolate = args.GetIsolate();
267   v8::HandleScope handleScope( isolate );
268   RenderTask renderTask = GetRenderTask( isolate, args );
269
270   // wrap the image
271   // @TODO Test this, may need to implement a Framebuffer image wrapper.?
272   v8::Local<v8::Object> localObject = ImageWrapper::WrapImage( isolate, renderTask.GetTargetFrameBuffer(),ImageWrapper::FRAME_BUFFER_IMAGE );
273   args.GetReturnValue().Set( localObject );
274 }
275
276
277 /**
278  * Set the actor used to convert screen coordinates to frame-buffer coordinates.
279  *
280  * The local coordinates of the actor are mapped as frame-buffer coordinates.
281  * This is useful for hit-testing actors which are rendered off-screen.
282  * Note: The mapping actor needs to be rendered by the default render task to make the mapping work properly.
283  * @method setScreenToFrameBufferMappingActor
284  * @for RenderTask
285  * @param {Object}  mappingActor The actor used for conversion.
286  */
287 void RenderTaskApi::SetScreenToFrameBufferMappingActor( const v8::FunctionCallbackInfo< v8::Value >& args )
288 {
289   v8::Isolate* isolate = args.GetIsolate();
290   v8::HandleScope handleScope( isolate );
291   RenderTask renderTask = GetRenderTask( isolate, args );
292   bool found( false );
293   Actor sourceActor = V8Utils::GetActorParameter( PARAMETER_0, found, isolate, args );
294
295   if( found )
296   {
297     renderTask.SetScreenToFrameBufferMappingActor( sourceActor );
298   }
299   else
300   {
301       DALI_SCRIPT_EXCEPTION( isolate, "source actor not found" );
302   }
303 }
304
305 /**
306  * Retrieve the actor used to convert screen coordinates to frame-buffer coordinates.
307  *
308  * @method getScreenToFrameBufferMappingActor
309  * @for RenderTask
310  * @return {Object} actor used for conversion.
311  */
312 void RenderTaskApi::GetScreenToFrameBufferMappingActor( const v8::FunctionCallbackInfo< v8::Value >& args )
313 {
314   v8::Isolate* isolate = args.GetIsolate();
315   v8::HandleScope handleScope( isolate );
316   RenderTask renderTask = GetRenderTask( isolate, args );
317
318   Actor source = renderTask.GetScreenToFrameBufferMappingActor();
319
320   v8::Handle < v8::Object > wrappedActor = ActorWrapper::WrapActor( isolate, source );
321   args.GetReturnValue().Set( wrappedActor );
322 }
323
324 /**
325  * Retrieve the GL viewport used when rendering.
326  *
327  * @method getViewport
328  * @for RenderTask
329  * @return {Object} object with the properties { x,y,width,height }
330  */
331 void RenderTaskApi::GetViewport( const v8::FunctionCallbackInfo< v8::Value >& args )
332 {
333   v8::Isolate* isolate = args.GetIsolate();
334   v8::HandleScope handleScope( isolate );
335   RenderTask renderTask = GetRenderTask( isolate, args );
336
337   v8::Local<v8::Object> viewportObject = v8::Object::New( isolate );
338
339   Viewport viewPort = renderTask.GetViewport();
340
341   viewportObject->Set( v8::String::NewFromUtf8( isolate, "x"), v8::Number::New( isolate,viewPort.x ));
342   viewportObject->Set( v8::String::NewFromUtf8( isolate, "y"), v8::Number::New( isolate,viewPort.y ));
343   viewportObject->Set( v8::String::NewFromUtf8( isolate, "width"), v8::Number::New( isolate,viewPort.width ));
344   viewportObject->Set( v8::String::NewFromUtf8( isolate, "height"), v8::Number::New( isolate,viewPort.height ));
345
346   args.GetReturnValue().Set( viewportObject );
347
348 }
349
350 /**
351  * Set the GL viewport used when rendering.
352  * This specifies the transformation between normalized device coordinates and target window (or frame-buffer) coordinates.
353  * By default this will match the target window or frame-buffer size.
354  * Unlike the glViewport method, the x & y coordinates refer to the top-left of the viewport rectangle.
355  * @method setViewport
356  * @for RenderTask
357  * @param {Object} object with the properties { x,y,width,height }
358  */
359 void RenderTaskApi::SetViewport( const v8::FunctionCallbackInfo< v8::Value >& args )
360 {
361   v8::Isolate* isolate = args.GetIsolate();
362   v8::HandleScope handleScope( isolate );
363   RenderTask renderTask = GetRenderTask( isolate, args );
364
365   if( args.Length() != 1 )
366   {
367      DALI_SCRIPT_EXCEPTION( isolate, "missing / invalid parameters" );
368      return;
369   }
370   v8::Local<v8::Value > viewportValue = args[0];
371   if( !viewportValue->IsObject() )
372   {
373     DALI_SCRIPT_EXCEPTION( isolate, "invalid parameters" );
374     return;
375   }
376   v8::Local<v8::Object> obj = viewportValue->ToObject();
377   v8::Local<v8::Value> xValue = obj->Get( v8::String::NewFromUtf8( isolate, "x" ) );
378   v8::Local<v8::Value> yValue = obj->Get( v8::String::NewFromUtf8( isolate, "y" ) );
379   v8::Local<v8::Value> widthValue = obj->Get( v8::String::NewFromUtf8( isolate, "width" ) );
380   v8::Local<v8::Value> heightValue = obj->Get( v8::String::NewFromUtf8( isolate, "height" ) );
381
382   if( xValue->IsNumber() &&  yValue->IsNumber() &&   widthValue->IsNumber() &&  heightValue->IsNumber())
383   {
384     Viewport viewPort;
385     viewPort.x= xValue->ToNumber()->Value();
386     viewPort.y = yValue->ToNumber()->Value();
387     viewPort.width = widthValue->ToNumber()->Value();
388     viewPort.height = heightValue->ToNumber()->Value();
389     renderTask.SetViewport( viewPort );
390   }
391   else
392   {
393     DALI_SCRIPT_EXCEPTION( isolate, "missing x,y,width,height property" );
394     return;
395   }
396 }
397
398 /**
399  * Set whether the render-task will clear the results of previous render-tasks.
400  *
401  * The default is false.
402  *
403  * The default GL surface is cleared automatically at the
404  * beginning of each frame; this setting is only useful when 2+
405  * render-tasks are used, and the result of the first task needs to
406  * be (partially) cleared before rendering the second. * @method setViewport
407  * @for RenderTask
408  * @method setClearEnabled
409  * @param {Boolean} enabled True if the render-task should clear
410  */
411 void RenderTaskApi::SetClearEnabled( const v8::FunctionCallbackInfo< v8::Value >& args )
412 {
413   v8::Isolate* isolate = args.GetIsolate();
414   v8::HandleScope handleScope( isolate );
415   RenderTask renderTask = GetRenderTask( isolate, args );
416
417   bool found( false );
418   bool clearEnabled = V8Utils::GetBooleanParameter( PARAMETER_0, found, isolate, args );
419   if( !found )
420   {
421     DALI_SCRIPT_EXCEPTION( isolate, "boolean parameter missing" );
422     return;
423   }
424   renderTask.SetClearEnabled( clearEnabled );
425
426 }
427
428 /**
429  * Query whether the render-task will clear the results of previous render-tasks.
430  *
431  * @for RenderTask
432  * @method getClearEnabled
433  * @return {Boolean} True if the render-task should clear.
434  */
435 void RenderTaskApi::GetClearEnabled( const v8::FunctionCallbackInfo< v8::Value >& args )
436 {
437   v8::Isolate* isolate = args.GetIsolate();
438   v8::HandleScope handleScope( isolate );
439   RenderTask renderTask = GetRenderTask( isolate, args );
440
441   args.GetReturnValue().Set( v8::Boolean::New( isolate, renderTask.GetClearEnabled() ) );
442 }
443
444 /**
445  * Set whether the render task will cull the actors to the camera's view frustum.
446  * Note that this will only affect image actors that use the default vertex shader.
447  * The default mode is to cull actors.
448  * @for RenderTask
449  * @method setCullMode
450  * @param {Boolean}  cullMode True if the renderers should be culled.
451  */
452 void RenderTaskApi::SetCullMode ( const v8::FunctionCallbackInfo< v8::Value >& args )
453 {
454   v8::Isolate* isolate = args.GetIsolate();
455   v8::HandleScope handleScope( isolate );
456   RenderTask renderTask = GetRenderTask( isolate, args );
457
458   bool found( false );
459   bool cullMode = V8Utils::GetBooleanParameter( PARAMETER_0, found, isolate, args );
460   if( !found )
461   {
462     DALI_SCRIPT_EXCEPTION( isolate, "boolean parameter missing" );
463     return;
464   }
465   renderTask.SetCullMode( cullMode );
466 }
467
468 /**
469  * Get the cull mode
470  * @for RenderTask
471  * @method getCullMode
472  * @return {Boolean}  cullMode True if the renderers should be culled.
473  */
474 void RenderTaskApi::GetCullMode( const v8::FunctionCallbackInfo< v8::Value >& args )
475 {
476   v8::Isolate* isolate = args.GetIsolate();
477   v8::HandleScope handleScope( isolate );
478   RenderTask renderTask = GetRenderTask( isolate, args );
479
480   args.GetReturnValue().Set( v8::Boolean::New( isolate, renderTask.GetCullMode() ) );
481 }
482
483 /**
484  * Set the refresh-rate of the RenderTask.
485  *
486  * The default is dali.REFRESH_ALWAYS (1), meaning that the RenderTask will be processed every frame.
487  * It may be desirable to process less frequently e.g. SetRefreshRate(3) will process once every 3 frames.
488  * The dali.REFRESH_ONCE value means that the RenderTask will be processed once only, to take a snap-shot of the scene.
489  * Repeatedly calling setRefreshRate(dali.REFRESH_ONCE) will cause more snap-shots to be taken.
490  * @method setRefreshRate
491  * @param {Integer} refresh rate  (0 =  dali.REFRESH_ONCE, 1= dali.REFRESH_ALWAYS)
492  */
493 void RenderTaskApi::SetRefreshRate( const v8::FunctionCallbackInfo< v8::Value >& args )
494 {
495   v8::Isolate* isolate = args.GetIsolate();
496   v8::HandleScope handleScope( isolate );
497   RenderTask renderTask = GetRenderTask( isolate, args );
498
499   bool found( false );
500   int rate = V8Utils::GetIntegerParameter( PARAMETER_0, found, isolate, args, 0 );
501   if( !found )
502   {
503      DALI_SCRIPT_EXCEPTION( isolate, "Integer parameter missing" );
504      return;
505   }
506   renderTask.SetRefreshRate( rate );
507 }
508
509 /**
510  *  Query the refresh-rate of the RenderTask.
511  * @method getRefreshRate
512  * @return {Integer} refresh rate  (0 =  dali.REFRESH_ONCE, 1= dali.REFRESH_ALWAYS)
513  */
514 void RenderTaskApi::GetRefreshRate( const v8::FunctionCallbackInfo< v8::Value >& args )
515 {
516   v8::Isolate* isolate = args.GetIsolate();
517   v8::HandleScope handleScope( isolate );
518   RenderTask renderTask = GetRenderTask( isolate, args );
519
520   args.GetReturnValue().Set( v8::Integer::New( isolate, renderTask.GetRefreshRate() ) );
521 }
522
523
524 } // namespace V8Plugin
525
526 } // namespace Dali