Make blend for the opaque renderer when advanced blend equation is applied.
[platform/core/uifw/dali-core.git] / dali / internal / common / blending-options.cpp
1 /*
2  * Copyright (c) 2020 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/common/blending-options.h>
20
21 namespace // unnamed namespace
22 {
23
24 using namespace Dali;
25
26 const int MASK_SRC_FACTOR_RGB    = 0x0000000F;
27 const int MASK_SRC_FACTOR_ALPHA  = 0x000000F0;
28 const int MASK_DEST_FACTOR_RGB   = 0x00000F00;
29 const int MASK_DEST_FACTOR_ALPHA = 0x0000F000;
30 const int MASK_EQUATION_RGB      = 0x00FF0000;
31 const int MASK_EQUATION_ALPHA    = 0xFF000000;
32
33 const int SHIFT_TO_SRC_FACTOR_RGB    =  0;
34 const int SHIFT_TO_SRC_FACTOR_ALPHA  =  4;
35 const int SHIFT_TO_DEST_FACTOR_RGB   =  8;
36 const int SHIFT_TO_DEST_FACTOR_ALPHA = 12;
37 const int SHIFT_TO_EQUATION_RGB      = 16;
38 const int SHIFT_TO_EQUATION_ALPHA    = 24;
39
40 static unsigned int CLEAR_BLEND_FUNC_MASK     = 0xFFFF0000; // Bottom 16 bits cleared
41 static unsigned int CLEAR_BLEND_EQUATION_MASK = 0x0000FFFF; // Top 16 bits cleared
42
43 /**
44  * Utility to store one of the BlendFunc values.
45  * @param[out] options A bitmask used to store the BlendFunc values.
46  * @param[in] factor The BlendFunc value.
47  * @param[in] bitshift Used to shift to the correct part of options.
48  */
49 void StoreBlendFactor( unsigned int& options, BlendFactor::Type factor, int bitShift )
50 {
51   switch( factor )
52   {
53     case BlendFactor::ZERO:
54     {
55       options |= ( 0u << bitShift );
56       break;
57     }
58
59     case BlendFactor::ONE:
60     {
61       options |= ( 1u << bitShift );
62       break;
63     }
64
65     case BlendFactor::SRC_COLOR:
66     {
67       options |= ( 2u << bitShift );
68       break;
69     }
70
71     case BlendFactor::ONE_MINUS_SRC_COLOR:
72     {
73       options |= ( 3u << bitShift );
74       break;
75     }
76
77     case BlendFactor::SRC_ALPHA:
78     {
79       options |= ( 4u << bitShift );
80       break;
81     }
82
83     case BlendFactor::ONE_MINUS_SRC_ALPHA:
84     {
85       options |= ( 5u << bitShift );
86       break;
87     }
88
89     case BlendFactor::DST_ALPHA:
90     {
91       options |= ( 6u << bitShift );
92       break;
93     }
94
95     case BlendFactor::ONE_MINUS_DST_ALPHA:
96     {
97       options |= ( 7u << bitShift );
98       break;
99     }
100
101     case BlendFactor::DST_COLOR:
102     {
103       options |= ( 8u << bitShift );
104       break;
105     }
106
107     case BlendFactor::ONE_MINUS_DST_COLOR:
108     {
109       options |= ( 9u << bitShift );
110       break;
111     }
112
113     case BlendFactor::SRC_ALPHA_SATURATE:
114     {
115       options |= ( 10u << bitShift );
116       break;
117     }
118
119     case BlendFactor::CONSTANT_COLOR:
120     {
121       options |= ( 11u << bitShift );
122       break;
123     }
124
125     case BlendFactor::ONE_MINUS_CONSTANT_COLOR:
126     {
127       options |= ( 12u << bitShift );
128       break;
129     }
130
131     case BlendFactor::CONSTANT_ALPHA:
132     {
133       options |= ( 13u << bitShift );
134       break;
135     }
136
137     case BlendFactor::ONE_MINUS_CONSTANT_ALPHA:
138     {
139       options |= ( 14u << bitShift );
140       break;
141     }
142   }
143 }
144
145 /**
146  * Utility to store one of the BlendEquation values.
147  * @param[out] options A bitmask used to store the BlendEquation values.
148  * @param[in] factor The BlendEquation value.
149  * @param[in] bitshift Used to shift to the correct part of options.
150  */
151 void StoreBlendEquation( unsigned int& options, DevelBlendEquation::Type factor, int bitShift )
152 {
153   // Must be same order as BLENDING_EQUATIONS, below:
154   enum {
155     ADD_BITVAL = 0u,
156     SUBTRACT_BITVAL,
157     REVERSE_SUBTRACT_BITVAL,
158     MIN_BITVAL,
159     MAX_BITVAL,
160     MULTIPLY_BITVAL,
161     SCREEN_BITVAL,
162     OVERLAY_BITVAL,
163     DARKEN_BITVAL,
164     LIGHTEN_BITVAL,
165     COLOR_DODGE_BITVAL,
166     COLOR_BURN_BITVAL,
167     HARD_LIGHT_BITVAL,
168     SOFT_LIGHT_BITVAL,
169     DIFFERENCE_BITVAL,
170     EXCLUSION_BITVAL,
171     HUE_BITVAL,
172     SATURATION_BITVAL,
173     COLOR_BITVAL,
174     LUMINOSITY_BITVAL
175   };
176
177   switch ( factor )
178   {
179     case DevelBlendEquation::ADD:
180     {
181       options |= ( ADD_BITVAL << bitShift );
182       break;
183     }
184
185     case DevelBlendEquation::SUBTRACT:
186     {
187       options |= ( SUBTRACT_BITVAL << bitShift );
188       break;
189     }
190
191     case DevelBlendEquation::REVERSE_SUBTRACT:
192     {
193       options |= ( REVERSE_SUBTRACT_BITVAL << bitShift );
194       break;
195     }
196
197     case DevelBlendEquation::MIN:
198     {
199       options |= ( MIN_BITVAL << bitShift );
200       break;
201     }
202
203     case DevelBlendEquation::MAX:
204     {
205       options |= ( MAX_BITVAL << bitShift );
206       break;
207     }
208
209     case DevelBlendEquation::MULTIPLY:
210     {
211       options |= ( MULTIPLY_BITVAL << bitShift );
212       break;
213     }
214
215     case DevelBlendEquation::SCREEN:
216     {
217       options |= ( SCREEN_BITVAL << bitShift );
218       break;
219     }
220
221     case DevelBlendEquation::OVERLAY:
222     {
223       options |= ( OVERLAY_BITVAL << bitShift );
224       break;
225     }
226
227     case DevelBlendEquation::DARKEN:
228     {
229       options |= ( DARKEN_BITVAL << bitShift );
230       break;
231     }
232
233     case DevelBlendEquation::LIGHTEN:
234     {
235       options |= ( LIGHTEN_BITVAL << bitShift );
236       break;
237     }
238
239     case DevelBlendEquation::COLOR_DODGE:
240     {
241       options |= ( COLOR_DODGE_BITVAL << bitShift );
242       break;
243     }
244
245     case DevelBlendEquation::COLOR_BURN:
246     {
247       options |= ( COLOR_BURN_BITVAL << bitShift );
248       break;
249     }
250
251     case DevelBlendEquation::HARD_LIGHT:
252     {
253       options |= ( HARD_LIGHT_BITVAL << bitShift );
254       break;
255     }
256
257     case DevelBlendEquation::SOFT_LIGHT:
258     {
259       options |= ( SOFT_LIGHT_BITVAL << bitShift );
260       break;
261     }
262
263     case DevelBlendEquation::DIFFERENCE:
264     {
265       options |= ( DIFFERENCE_BITVAL << bitShift );
266       break;
267     }
268
269     case DevelBlendEquation::EXCLUSION:
270     {
271       options |= ( EXCLUSION_BITVAL << bitShift );
272       break;
273     }
274
275     case DevelBlendEquation::HUE:
276     {
277       options |= ( HUE_BITVAL << bitShift );
278       break;
279     }
280
281     case DevelBlendEquation::SATURATION:
282     {
283       options |= ( SATURATION_BITVAL << bitShift );
284       break;
285     }
286
287     case DevelBlendEquation::COLOR:
288     {
289       options |= ( COLOR_BITVAL << bitShift );
290       break;
291     }
292
293     case DevelBlendEquation::LUMINOSITY:
294     {
295       options |= ( LUMINOSITY_BITVAL << bitShift );
296       break;
297     }
298   }
299 }
300
301 const unsigned int BLENDING_FACTOR_COUNT   = 15;
302 const unsigned int BLENDING_EQUATION_COUNT = 20;
303 const unsigned int BLENDING_EQUATION_ADVANCED_INDEX_START = 5;
304 const unsigned int BLENDING_EQUATION_ADVANCED_INDEX_END = 19;
305
306 BlendFactor::Type BLENDING_FACTORS[ BLENDING_FACTOR_COUNT ] =
307 {
308   BlendFactor::ZERO,
309   BlendFactor::ONE,
310   BlendFactor::SRC_COLOR,
311   BlendFactor::ONE_MINUS_SRC_COLOR,
312   BlendFactor::SRC_ALPHA,
313   BlendFactor::ONE_MINUS_SRC_ALPHA,
314   BlendFactor::DST_ALPHA,
315   BlendFactor::ONE_MINUS_DST_ALPHA,
316   BlendFactor::DST_COLOR,
317   BlendFactor::ONE_MINUS_DST_COLOR,
318   BlendFactor::SRC_ALPHA_SATURATE,
319   BlendFactor::CONSTANT_COLOR,
320   BlendFactor::ONE_MINUS_CONSTANT_COLOR,
321   BlendFactor::CONSTANT_ALPHA,
322   BlendFactor::ONE_MINUS_CONSTANT_ALPHA
323 };
324
325 DevelBlendEquation::Type BLENDING_EQUATIONS[ BLENDING_EQUATION_COUNT ] =
326 {
327   DevelBlendEquation::ADD,
328   DevelBlendEquation::SUBTRACT,
329   DevelBlendEquation::REVERSE_SUBTRACT,
330   DevelBlendEquation::MIN,
331   DevelBlendEquation::MAX,
332   DevelBlendEquation::MULTIPLY,
333   DevelBlendEquation::SCREEN,
334   DevelBlendEquation::OVERLAY,
335   DevelBlendEquation::DARKEN,
336   DevelBlendEquation::LIGHTEN,
337   DevelBlendEquation::COLOR_DODGE,
338   DevelBlendEquation::COLOR_BURN,
339   DevelBlendEquation::HARD_LIGHT,
340   DevelBlendEquation::SOFT_LIGHT,
341   DevelBlendEquation::DIFFERENCE,
342   DevelBlendEquation::EXCLUSION,
343   DevelBlendEquation::HUE,
344   DevelBlendEquation::SATURATION,
345   DevelBlendEquation::COLOR,
346   DevelBlendEquation::LUMINOSITY
347 };
348
349 /**
350  * Utility to retrieve one of the BlendFunc values.
351  * @param[in] options A bitmask of blending values.
352  * @param[in] mask The used to mask unwanted values.
353  * @param[in] bitshift Used to shift to the correct part of options.
354  * @return The blending factor.
355  */
356 BlendFactor::Type RetrieveBlendFactor( unsigned int options, int mask, int bitShift )
357 {
358   unsigned int index = options & mask;
359   index = index >> bitShift;
360
361   DALI_ASSERT_DEBUG( index < BLENDING_FACTOR_COUNT );
362
363   return BLENDING_FACTORS[ index ];
364 }
365
366 /**
367  * Utility to retrieve one of the BlendEquation values.
368  * @param[in] options A bitmask of blending values.
369  * @param[in] mask The used to mask unwanted values.
370  * @param[in] bitshift Used to shift to the correct part of options.
371  * @return The blending equation.
372  */
373 DevelBlendEquation::Type RetrieveBlendEquation( unsigned int options, int mask, int bitShift )
374 {
375   unsigned int index = options & mask;
376   index = index >> bitShift;
377
378   DALI_ASSERT_DEBUG( index < BLENDING_EQUATION_COUNT );
379
380   return BLENDING_EQUATIONS[ index ];
381 }
382
383 } // unnamed namespace
384
385 namespace Dali
386 {
387
388 namespace Internal
389 {
390
391 BlendingOptions::BlendingOptions()
392 : mBitmask( 0u ),
393   mBlendColor( nullptr )
394 {
395   SetBlendFunc( BlendFactor::SRC_ALPHA, BlendFactor::ONE_MINUS_SRC_ALPHA,
396                 BlendFactor::ONE,       BlendFactor::ONE_MINUS_SRC_ALPHA );
397
398   SetBlendEquation( DevelBlendEquation::ADD, DevelBlendEquation::ADD );
399 }
400
401 BlendingOptions::~BlendingOptions() = default;
402
403 void BlendingOptions::SetBitmask( unsigned int bitmask )
404 {
405   mBitmask = bitmask;
406 }
407
408 unsigned int BlendingOptions::GetBitmask() const
409 {
410   return mBitmask;
411 }
412
413 void BlendingOptions::SetBlendFunc( BlendFactor::Type srcFactorRgb,   BlendFactor::Type destFactorRgb,
414                                     BlendFactor::Type srcFactorAlpha, BlendFactor::Type destFactorAlpha )
415 {
416   mBitmask &= CLEAR_BLEND_FUNC_MASK; // Clear the BlendFunc values
417
418   StoreBlendFactor( mBitmask, srcFactorRgb,    SHIFT_TO_SRC_FACTOR_RGB );
419   StoreBlendFactor( mBitmask, destFactorRgb,   SHIFT_TO_DEST_FACTOR_RGB );
420   StoreBlendFactor( mBitmask, srcFactorAlpha,  SHIFT_TO_SRC_FACTOR_ALPHA );
421   StoreBlendFactor( mBitmask, destFactorAlpha, SHIFT_TO_DEST_FACTOR_ALPHA );
422 }
423
424 BlendFactor::Type BlendingOptions::GetBlendSrcFactorRgb() const
425 {
426   return RetrieveBlendFactor( mBitmask, MASK_SRC_FACTOR_RGB,  SHIFT_TO_SRC_FACTOR_RGB );
427 }
428
429 BlendFactor::Type BlendingOptions::GetBlendDestFactorRgb() const
430 {
431   return RetrieveBlendFactor( mBitmask, MASK_DEST_FACTOR_RGB, SHIFT_TO_DEST_FACTOR_RGB );
432 }
433
434 BlendFactor::Type BlendingOptions::GetBlendSrcFactorAlpha() const
435 {
436   return RetrieveBlendFactor( mBitmask, MASK_SRC_FACTOR_ALPHA,  SHIFT_TO_SRC_FACTOR_ALPHA );
437 }
438
439 BlendFactor::Type BlendingOptions::GetBlendDestFactorAlpha() const
440 {
441   return RetrieveBlendFactor( mBitmask, MASK_DEST_FACTOR_ALPHA, SHIFT_TO_DEST_FACTOR_ALPHA );
442 }
443
444 void BlendingOptions::SetBlendEquation( DevelBlendEquation::Type equationRgb, DevelBlendEquation::Type equationAlpha )
445 {
446   mBitmask &= CLEAR_BLEND_EQUATION_MASK; // Clear the BlendEquation values
447
448   StoreBlendEquation( mBitmask, equationRgb,   SHIFT_TO_EQUATION_RGB );
449   StoreBlendEquation( mBitmask, equationAlpha, SHIFT_TO_EQUATION_ALPHA );
450 }
451
452 DevelBlendEquation::Type BlendingOptions::GetBlendEquationRgb() const
453 {
454   return RetrieveBlendEquation( mBitmask, MASK_EQUATION_RGB, SHIFT_TO_EQUATION_RGB );
455 }
456
457 DevelBlendEquation::Type BlendingOptions::GetBlendEquationAlpha() const
458 {
459   return RetrieveBlendEquation( mBitmask, MASK_EQUATION_ALPHA, SHIFT_TO_EQUATION_ALPHA );
460 }
461
462 void BlendingOptions::SetBlendColor( const Vector4& color )
463 {
464   if( Color::TRANSPARENT == color )
465   {
466     mBlendColor = nullptr;
467   }
468   else
469   {
470     if( mBlendColor )
471     {
472       *mBlendColor = color;
473     }
474     else
475     {
476       // Lazy allocation when non-default is set
477       mBlendColor = new Vector4( color );
478     }
479   }
480 }
481
482 const Vector4* BlendingOptions::GetBlendColor() const
483 {
484   return mBlendColor.Get();
485 }
486
487 bool BlendingOptions::IsAdvancedBlendEquationApplied()
488 {
489   unsigned int indexRgb = mBitmask & MASK_EQUATION_RGB;
490   indexRgb = indexRgb >> SHIFT_TO_EQUATION_RGB;
491   unsigned int indexA = mBitmask & MASK_EQUATION_ALPHA;
492   indexA = indexA >> SHIFT_TO_EQUATION_ALPHA;
493
494   return ( ( ( indexRgb >= BLENDING_EQUATION_ADVANCED_INDEX_START ) && ( indexRgb <= BLENDING_EQUATION_ADVANCED_INDEX_END ) ) ||
495            ( ( indexA   >= BLENDING_EQUATION_ADVANCED_INDEX_START ) && ( indexA   <= BLENDING_EQUATION_ADVANCED_INDEX_END ) ) );
496 }
497
498 bool BlendingOptions::IsAdvancedBlendEquationIncluded( unsigned int bitmask )
499 {
500   unsigned int indexRgb = bitmask & MASK_EQUATION_RGB;
501   indexRgb = indexRgb >> SHIFT_TO_EQUATION_RGB;
502   unsigned int indexA = bitmask & MASK_EQUATION_ALPHA;
503   indexA = indexA >> SHIFT_TO_EQUATION_ALPHA;
504
505   return ( ( ( indexRgb >= BLENDING_EQUATION_ADVANCED_INDEX_START ) && ( indexRgb <= BLENDING_EQUATION_ADVANCED_INDEX_END ) ) ||
506            ( ( indexA   >= BLENDING_EQUATION_ADVANCED_INDEX_START ) && ( indexA   <= BLENDING_EQUATION_ADVANCED_INDEX_END ) ) );
507 }
508
509 bool BlendingOptions::IsAdvancedBlendEquation( DevelBlendEquation::Type equation )
510 {
511   switch ( equation )
512   {
513     case DevelBlendEquation::MULTIPLY:
514     case DevelBlendEquation::SCREEN:
515     case DevelBlendEquation::OVERLAY:
516     case DevelBlendEquation::DARKEN:
517     case DevelBlendEquation::LIGHTEN:
518     case DevelBlendEquation::COLOR_DODGE:
519     case DevelBlendEquation::COLOR_BURN:
520     case DevelBlendEquation::HARD_LIGHT:
521     case DevelBlendEquation::SOFT_LIGHT:
522     case DevelBlendEquation::DIFFERENCE:
523     case DevelBlendEquation::EXCLUSION:
524     case DevelBlendEquation::HUE:
525     case DevelBlendEquation::SATURATION:
526     case DevelBlendEquation::COLOR:
527     case DevelBlendEquation::LUMINOSITY:
528     {
529       return true;
530     }
531
532     default:
533     {
534       return false;
535     }
536   }
537 }
538
539 } // namespace Internal
540
541 } // namespace Dali