Refactored old API from RenderableActor into ImageActor.
[platform/core/uifw/dali-core.git] / dali / internal / event / actor-attachments / image-attachment-impl.cpp
1 /*
2  * Copyright (c) 2014 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 // CLASS HEADER
19 #include <dali/internal/event/actor-attachments/image-attachment-impl.h>
20
21 // INTERNAL INCLUDES
22 #include <dali/internal/update/node-attachments/scene-graph-image-attachment.h>
23 #include <dali/internal/event/common/stage-impl.h>
24 #include <dali/public-api/common/dali-common.h>
25 #include <dali/internal/event/effects/shader-effect-impl.h>
26 #include <dali/internal/render/shaders/scene-graph-shader.h>
27
28 namespace Dali
29 {
30
31 namespace Internal
32 {
33
34 ImageAttachmentPtr ImageAttachment::New( Stage& stage, const SceneGraph::Node& parentNode )
35 {
36   ImageAttachmentPtr attachment( new ImageAttachment( stage ) );
37
38   // Transfer object ownership of scene-object to message
39   SceneGraph::ImageAttachment* sceneObject = CreateSceneObject();
40   AttachToNodeMessage( stage.GetUpdateManager(), parentNode, sceneObject );
41
42   // Keep raw pointer for message passing
43   attachment->mSceneObject = sceneObject;
44
45   return attachment;
46 }
47
48 ImageAttachment::ImageAttachment( Stage& stage )
49 : RenderableAttachment(stage),
50   mSceneObject(NULL),
51   mPixelArea(0,0,0,0),
52   mStyle(Dali::ImageActor::STYLE_QUAD),
53   mBorder(0.45,0.45,0.1,0.1),
54   mIsPixelAreaSet(false),
55   mBorderInPixels(false),
56
57
58   mBlendingOptions(),
59   mSamplerBitfield( ImageSampler::PackBitfield( FilterMode::DEFAULT, FilterMode::DEFAULT ) ),
60   mSortModifier( 0.0f ),
61   mCullFaceMode( CullNone ),
62   mBlendingMode( BlendingMode::AUTO ),
63   mShaderEffect()
64 {
65   mImageConnectable.Set( NULL, false );
66 }
67
68 ImageAttachment::~ImageAttachment()
69 {
70 }
71
72 void ImageAttachment::SetImage( ImagePtr& image )
73 {
74   bool onStage = OnStage();
75   // keep a reference to Image object
76   mImageConnectable.Set( image, onStage );
77
78   // Wait until the scene-graph attachment is connected, before providing resource ID
79   if ( OnStage() )
80   {
81     unsigned int resourceId = (image) ? image->GetResourceId() : 0u;
82
83     // sceneObject is being used in a separate thread; queue a message to set
84     SetTextureIdMessage( mStage->GetUpdateInterface(), *mSceneObject, resourceId );
85   }
86 }
87
88 ImagePtr ImageAttachment::GetImage()
89 {
90   return mImageConnectable.Get();
91 }
92
93 void ImageAttachment::SetPixelArea(const PixelArea& pixelArea)
94 {
95   // check to see if pixel area is actually different, using rect::operator==
96   if( pixelArea != mPixelArea )
97   {
98     // Cache for public getters
99     mPixelArea = pixelArea;
100     mIsPixelAreaSet = true;
101
102     // sceneObject is being used in a separate thread; queue a message to set
103     SetPixelAreaMessage( mStage->GetUpdateInterface(), *mSceneObject, mPixelArea );
104   }
105 }
106
107 void ImageAttachment::ClearPixelArea()
108 {
109   // Cache for public getters
110   mIsPixelAreaSet = false;
111
112   // sceneObject is being used in a separate thread; queue a message to set
113   ClearPixelAreaMessage( mStage->GetUpdateInterface(), *mSceneObject );
114 }
115
116 void ImageAttachment::SetStyle(Style style)
117 {
118   // Cache for public getters
119   mStyle = style;
120
121   // sceneObject is being used in a separate thread; queue a message to set
122   SetStyleMessage( mStage->GetUpdateInterface(), *mSceneObject, style );
123 }
124
125 void ImageAttachment::SetNinePatchBorder(const Vector4& border, bool inPixels)
126 {
127   // Cache for public getters
128   mBorder = border;
129   mBorderInPixels = inPixels;
130
131   // sceneObject is being used in a separate thread; queue a message to set
132   SetNinePatchBorderMessage( mStage->GetUpdateInterface(), *mSceneObject, border, inPixels );
133 }
134
135 SceneGraph::ImageAttachment* ImageAttachment::CreateSceneObject()
136 {
137   return SceneGraph::ImageAttachment::New( 0u );
138 }
139
140 const SceneGraph::RenderableAttachment& ImageAttachment::GetSceneObject() const
141 {
142   DALI_ASSERT_DEBUG( mSceneObject != NULL );
143   return *mSceneObject;
144 }
145
146
147 void ImageAttachment::SetSortModifier(float modifier)
148 {
149   // Cache for actor-side getters
150   mSortModifier = modifier;
151
152   // attachment is being used in a separate thread; queue a message to set the value & base value
153   SetSortModifierMessage( mStage->GetUpdateInterface(), GetSceneObject(), modifier );
154 }
155
156 float ImageAttachment::GetSortModifier() const
157 {
158   // mSortModifier is not animatable; this is the most up-to-date value.
159   return mSortModifier;
160 }
161
162 void ImageAttachment::SetCullFace( CullFaceMode mode )
163 {
164   // Cache for actor-side getters
165   mCullFaceMode = mode;
166
167   // attachment is being used in a separate thread; queue a message to set the value
168   SetCullFaceMessage( mStage->GetUpdateInterface(), GetSceneObject(), mode );
169 }
170
171 CullFaceMode ImageAttachment::GetCullFace() const
172 {
173   // mCullFaceMode is not animatable; this is the most up-to-date value.
174   return mCullFaceMode;
175 }
176
177 void ImageAttachment::SetBlendMode( BlendingMode::Type mode )
178 {
179   mBlendingMode = mode;
180
181   // attachment is being used in a separate thread; queue a message to set the value
182   SetBlendingModeMessage( mStage->GetUpdateInterface(), GetSceneObject(), mode );
183 }
184
185 BlendingMode::Type ImageAttachment::GetBlendMode() const
186 {
187   return mBlendingMode;
188 }
189
190 void ImageAttachment::SetBlendFunc( BlendingFactor::Type srcFactorRgb,   BlendingFactor::Type destFactorRgb,
191                                          BlendingFactor::Type srcFactorAlpha, BlendingFactor::Type destFactorAlpha )
192 {
193   // Cache for actor-side getters
194   mBlendingOptions.SetBlendFunc( srcFactorRgb, destFactorRgb, srcFactorAlpha, destFactorAlpha );
195
196   // attachment is being used in a separate thread; queue a message to set the value
197   SetBlendingOptionsMessage( mStage->GetUpdateInterface(), GetSceneObject(), mBlendingOptions.GetBitmask() );
198 }
199
200 void ImageAttachment::GetBlendFunc( BlendingFactor::Type& srcFactorRgb,   BlendingFactor::Type& destFactorRgb,
201                                          BlendingFactor::Type& srcFactorAlpha, BlendingFactor::Type& destFactorAlpha ) const
202 {
203   // These are not animatable, the cached values are up-to-date.
204   srcFactorRgb    = mBlendingOptions.GetBlendSrcFactorRgb();
205   destFactorRgb   = mBlendingOptions.GetBlendDestFactorRgb();
206   srcFactorAlpha  = mBlendingOptions.GetBlendSrcFactorAlpha();
207   destFactorAlpha = mBlendingOptions.GetBlendDestFactorAlpha();
208 }
209
210 void ImageAttachment::SetBlendEquation( BlendingEquation::Type equationRgb, BlendingEquation::Type equationAlpha )
211 {
212   mBlendingOptions.SetBlendEquation( equationRgb, equationAlpha );
213
214   // attachment is being used in a separate thread; queue a message to set the value
215   SetBlendingOptionsMessage( mStage->GetUpdateInterface(), GetSceneObject(), mBlendingOptions.GetBitmask() );
216 }
217
218 void ImageAttachment::GetBlendEquation( BlendingEquation::Type& equationRgb, BlendingEquation::Type& equationAlpha ) const
219 {
220   // These are not animatable, the cached values are up-to-date.
221   equationRgb   = mBlendingOptions.GetBlendEquationRgb();
222   equationAlpha = mBlendingOptions.GetBlendEquationAlpha();
223 }
224
225 void ImageAttachment::SetBlendColor( const Vector4& color )
226 {
227   if( mBlendingOptions.SetBlendColor( color ) )
228   {
229     // attachment is being used in a separate thread; queue a message to set the value
230     SetBlendColorMessage( mStage->GetUpdateInterface(), GetSceneObject(), color );
231   }
232 }
233
234 const Vector4& ImageAttachment::GetBlendColor() const
235 {
236   const Vector4* optionalColor = mBlendingOptions.GetBlendColor();
237   if( optionalColor )
238   {
239     return *optionalColor;
240   }
241
242   return Vector4::ZERO;
243 }
244
245 void ImageAttachment::SetFilterMode( FilterMode::Type minFilter, FilterMode::Type magFilter )
246 {
247   mSamplerBitfield = ImageSampler::PackBitfield( minFilter, magFilter );
248
249   SetSamplerMessage( mStage->GetUpdateInterface(), GetSceneObject(), mSamplerBitfield );
250 }
251
252 void ImageAttachment::GetFilterMode( FilterMode::Type& minFilter, FilterMode::Type& magFilter ) const
253 {
254   minFilter = ImageSampler::GetMinifyFilterMode( mSamplerBitfield );
255   magFilter = ImageSampler::GetMagnifyFilterMode( mSamplerBitfield );
256 }
257
258
259 void ImageAttachment::SetShaderEffect(ShaderEffect& effect)
260 {
261   if ( OnStage() )
262   {
263     if ( mShaderEffect )
264     {
265       mShaderEffect->Disconnect();
266     }
267
268     mShaderEffect.Reset( &effect );
269
270     const SceneGraph::Shader& shader = dynamic_cast<const SceneGraph::Shader&>( *mShaderEffect->GetSceneObject() );
271
272     ApplyShaderMessage( mStage->GetUpdateInterface(), GetSceneObject(), shader );
273
274     mShaderEffect->Connect();
275   }
276   else
277   {
278     mShaderEffect = ShaderEffectPtr(&effect);
279   }
280   // Effects can only be applied when the Node is connected to scene-graph
281 }
282
283 ShaderEffectPtr ImageAttachment::GetShaderEffect() const
284 {
285   return mShaderEffect;
286 }
287
288 void ImageAttachment::RemoveShaderEffect()
289 {
290   if ( OnStage() )
291   {
292     RemoveShaderMessage( mStage->GetUpdateInterface(), GetSceneObject() );
293
294     // Notify shader effect
295     if (mShaderEffect)
296     {
297       mShaderEffect->Disconnect();
298     }
299   }
300
301   mShaderEffect.Reset();
302 }
303
304
305 void ImageAttachment::OnStageConnection2()
306 {
307   if ( mShaderEffect )
308   {
309     const SceneGraph::Shader& shader = dynamic_cast<const SceneGraph::Shader&>( *mShaderEffect->GetSceneObject() );
310
311     ApplyShaderMessage( mStage->GetUpdateInterface(), GetSceneObject(), shader );
312
313     // Notify shader effect
314     mShaderEffect->Connect();
315   }
316
317   mImageConnectable.OnStageConnect();
318
319   // Provide resource ID when scene-graph attachment is connected
320   ImagePtr image = mImageConnectable.Get();
321   unsigned int resourceId = (image) ? image->GetResourceId() : 0u;
322   if ( 0u != resourceId )
323   {
324     SetTextureIdMessage( mStage->GetUpdateInterface(), *mSceneObject, resourceId );
325   }
326 }
327
328 void ImageAttachment::OnStageDisconnection2()
329 {
330   // Notify shader effect
331   if ( mShaderEffect )
332   {
333     mShaderEffect->Disconnect();
334   }
335
336   // Remove resource ID when scene-graph attachment is disconnected
337   SetTextureIdMessage( mStage->GetUpdateInterface(), *mSceneObject, 0u );
338
339   mImageConnectable.OnStageDisconnect();
340 }
341
342
343
344 } // namespace Internal
345
346 } // namespace Dali