Apply Visual's transform + borderline properties for partial update
[platform/core/uifw/dali-core.git] / dali / internal / common / blending-options.cpp
1 /*
2  * Copyright (c) 2021 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 using namespace Dali;
24
25 const int MASK_SRC_FACTOR_RGB    = 0x0000000F;
26 const int MASK_SRC_FACTOR_ALPHA  = 0x000000F0;
27 const int MASK_DEST_FACTOR_RGB   = 0x00000F00;
28 const int MASK_DEST_FACTOR_ALPHA = 0x0000F000;
29 const int MASK_EQUATION_RGB      = 0x00FF0000;
30 const int MASK_EQUATION_ALPHA    = 0xFF000000;
31
32 const int SHIFT_TO_SRC_FACTOR_RGB    = 0;
33 const int SHIFT_TO_SRC_FACTOR_ALPHA  = 4;
34 const int SHIFT_TO_DEST_FACTOR_RGB   = 8;
35 const int SHIFT_TO_DEST_FACTOR_ALPHA = 12;
36 const int SHIFT_TO_EQUATION_RGB      = 16;
37 const int SHIFT_TO_EQUATION_ALPHA    = 24;
38
39 static unsigned int CLEAR_BLEND_FUNC_MASK     = 0xFFFF0000; // Bottom 16 bits cleared
40 static unsigned int CLEAR_BLEND_EQUATION_MASK = 0x0000FFFF; // Top 16 bits cleared
41
42 /**
43  * Utility to store one of the BlendFunc values.
44  * @param[out] options A bitmask used to store the BlendFunc values.
45  * @param[in] factor The BlendFunc value.
46  * @param[in] bitshift Used to shift to the correct part of options.
47  */
48 void StoreBlendFactor(unsigned int& options, BlendFactor::Type factor, int bitShift)
49 {
50   switch(factor)
51   {
52     case BlendFactor::ZERO:
53     {
54       options |= (0u << bitShift);
55       break;
56     }
57
58     case BlendFactor::ONE:
59     {
60       options |= (1u << bitShift);
61       break;
62     }
63
64     case BlendFactor::SRC_COLOR:
65     {
66       options |= (2u << bitShift);
67       break;
68     }
69
70     case BlendFactor::ONE_MINUS_SRC_COLOR:
71     {
72       options |= (3u << bitShift);
73       break;
74     }
75
76     case BlendFactor::SRC_ALPHA:
77     {
78       options |= (4u << bitShift);
79       break;
80     }
81
82     case BlendFactor::ONE_MINUS_SRC_ALPHA:
83     {
84       options |= (5u << bitShift);
85       break;
86     }
87
88     case BlendFactor::DST_ALPHA:
89     {
90       options |= (6u << bitShift);
91       break;
92     }
93
94     case BlendFactor::ONE_MINUS_DST_ALPHA:
95     {
96       options |= (7u << bitShift);
97       break;
98     }
99
100     case BlendFactor::DST_COLOR:
101     {
102       options |= (8u << bitShift);
103       break;
104     }
105
106     case BlendFactor::ONE_MINUS_DST_COLOR:
107     {
108       options |= (9u << bitShift);
109       break;
110     }
111
112     case BlendFactor::SRC_ALPHA_SATURATE:
113     {
114       options |= (10u << bitShift);
115       break;
116     }
117
118     case BlendFactor::CONSTANT_COLOR:
119     {
120       options |= (11u << bitShift);
121       break;
122     }
123
124     case BlendFactor::ONE_MINUS_CONSTANT_COLOR:
125     {
126       options |= (12u << bitShift);
127       break;
128     }
129
130     case BlendFactor::CONSTANT_ALPHA:
131     {
132       options |= (13u << bitShift);
133       break;
134     }
135
136     case BlendFactor::ONE_MINUS_CONSTANT_ALPHA:
137     {
138       options |= (14u << bitShift);
139       break;
140     }
141   }
142 }
143
144 /**
145  * Utility to store one of the BlendEquation values.
146  * @param[out] options A bitmask used to store the BlendEquation values.
147  * @param[in] factor The BlendEquation value.
148  * @param[in] bitshift Used to shift to the correct part of options.
149  */
150 void StoreBlendEquation(unsigned int& options, DevelBlendEquation::Type factor, int bitShift)
151 {
152   // Must be same order as BLENDING_EQUATIONS, below:
153   enum
154   {
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 DevelBlendEquation::Type BLENDING_EQUATIONS[BLENDING_EQUATION_COUNT] =
325   {
326     DevelBlendEquation::ADD,
327     DevelBlendEquation::SUBTRACT,
328     DevelBlendEquation::REVERSE_SUBTRACT,
329     DevelBlendEquation::MIN,
330     DevelBlendEquation::MAX,
331     DevelBlendEquation::MULTIPLY,
332     DevelBlendEquation::SCREEN,
333     DevelBlendEquation::OVERLAY,
334     DevelBlendEquation::DARKEN,
335     DevelBlendEquation::LIGHTEN,
336     DevelBlendEquation::COLOR_DODGE,
337     DevelBlendEquation::COLOR_BURN,
338     DevelBlendEquation::HARD_LIGHT,
339     DevelBlendEquation::SOFT_LIGHT,
340     DevelBlendEquation::DIFFERENCE,
341     DevelBlendEquation::EXCLUSION,
342     DevelBlendEquation::HUE,
343     DevelBlendEquation::SATURATION,
344     DevelBlendEquation::COLOR,
345     DevelBlendEquation::LUMINOSITY};
346
347 /**
348  * Utility to retrieve one of the BlendFunc values.
349  * @param[in] options A bitmask of blending values.
350  * @param[in] mask The used to mask unwanted values.
351  * @param[in] bitshift Used to shift to the correct part of options.
352  * @return The blending factor.
353  */
354 BlendFactor::Type RetrieveBlendFactor(unsigned int options, int mask, int bitShift)
355 {
356   unsigned int index = options & mask;
357   index              = index >> bitShift;
358
359   DALI_ASSERT_DEBUG(index < BLENDING_FACTOR_COUNT);
360
361   return BLENDING_FACTORS[index];
362 }
363
364 /**
365  * Utility to retrieve one of the BlendEquation values.
366  * @param[in] options A bitmask of blending values.
367  * @param[in] mask The used to mask unwanted values.
368  * @param[in] bitshift Used to shift to the correct part of options.
369  * @return The blending equation.
370  */
371 DevelBlendEquation::Type RetrieveBlendEquation(unsigned int options, int mask, int bitShift)
372 {
373   unsigned int index = options & mask;
374   index              = index >> bitShift;
375
376   DALI_ASSERT_DEBUG(index < BLENDING_EQUATION_COUNT);
377
378   return BLENDING_EQUATIONS[index];
379 }
380
381 } // unnamed namespace
382
383 namespace Dali
384 {
385 namespace Internal
386 {
387 BlendingOptions::BlendingOptions()
388 : mBitmask(0u),
389   mBlendColor(nullptr)
390 {
391   SetBlendFunc(BlendFactor::SRC_ALPHA, BlendFactor::ONE_MINUS_SRC_ALPHA, BlendFactor::ONE, BlendFactor::ONE_MINUS_SRC_ALPHA);
392
393   SetBlendEquation(DevelBlendEquation::ADD, DevelBlendEquation::ADD);
394 }
395
396 BlendingOptions::~BlendingOptions() = default;
397
398 void BlendingOptions::SetBitmask(unsigned int bitmask)
399 {
400   mBitmask = bitmask;
401 }
402
403 unsigned int BlendingOptions::GetBitmask() const
404 {
405   return mBitmask;
406 }
407
408 void BlendingOptions::SetBlendFunc(BlendFactor::Type srcFactorRgb, BlendFactor::Type destFactorRgb, BlendFactor::Type srcFactorAlpha, BlendFactor::Type destFactorAlpha)
409 {
410   mBitmask &= CLEAR_BLEND_FUNC_MASK; // Clear the BlendFunc values
411
412   StoreBlendFactor(mBitmask, srcFactorRgb, SHIFT_TO_SRC_FACTOR_RGB);
413   StoreBlendFactor(mBitmask, destFactorRgb, SHIFT_TO_DEST_FACTOR_RGB);
414   StoreBlendFactor(mBitmask, srcFactorAlpha, SHIFT_TO_SRC_FACTOR_ALPHA);
415   StoreBlendFactor(mBitmask, destFactorAlpha, SHIFT_TO_DEST_FACTOR_ALPHA);
416 }
417
418 BlendFactor::Type BlendingOptions::GetBlendSrcFactorRgb() const
419 {
420   return RetrieveBlendFactor(mBitmask, MASK_SRC_FACTOR_RGB, SHIFT_TO_SRC_FACTOR_RGB);
421 }
422
423 BlendFactor::Type BlendingOptions::GetBlendDestFactorRgb() const
424 {
425   return RetrieveBlendFactor(mBitmask, MASK_DEST_FACTOR_RGB, SHIFT_TO_DEST_FACTOR_RGB);
426 }
427
428 BlendFactor::Type BlendingOptions::GetBlendSrcFactorAlpha() const
429 {
430   return RetrieveBlendFactor(mBitmask, MASK_SRC_FACTOR_ALPHA, SHIFT_TO_SRC_FACTOR_ALPHA);
431 }
432
433 BlendFactor::Type BlendingOptions::GetBlendDestFactorAlpha() const
434 {
435   return RetrieveBlendFactor(mBitmask, MASK_DEST_FACTOR_ALPHA, SHIFT_TO_DEST_FACTOR_ALPHA);
436 }
437
438 void BlendingOptions::SetBlendEquation(DevelBlendEquation::Type equationRgb, DevelBlendEquation::Type equationAlpha)
439 {
440   mBitmask &= CLEAR_BLEND_EQUATION_MASK; // Clear the BlendEquation values
441
442   StoreBlendEquation(mBitmask, equationRgb, SHIFT_TO_EQUATION_RGB);
443   StoreBlendEquation(mBitmask, equationAlpha, SHIFT_TO_EQUATION_ALPHA);
444 }
445
446 DevelBlendEquation::Type BlendingOptions::GetBlendEquationRgb() const
447 {
448   return RetrieveBlendEquation(mBitmask, MASK_EQUATION_RGB, SHIFT_TO_EQUATION_RGB);
449 }
450
451 DevelBlendEquation::Type BlendingOptions::GetBlendEquationAlpha() const
452 {
453   return RetrieveBlendEquation(mBitmask, MASK_EQUATION_ALPHA, SHIFT_TO_EQUATION_ALPHA);
454 }
455
456 void BlendingOptions::SetBlendColor(const Vector4& color)
457 {
458   if(Color::TRANSPARENT == color)
459   {
460     mBlendColor = nullptr;
461   }
462   else
463   {
464     if(mBlendColor)
465     {
466       *mBlendColor = color;
467     }
468     else
469     {
470       // Lazy allocation when non-default is set
471       mBlendColor = new Vector4(color);
472     }
473   }
474 }
475
476 const Vector4* BlendingOptions::GetBlendColor() const
477 {
478   return mBlendColor.Get();
479 }
480
481 bool BlendingOptions::IsAdvancedBlendEquationApplied()
482 {
483   unsigned int indexRgb = mBitmask & MASK_EQUATION_RGB;
484   indexRgb              = indexRgb >> SHIFT_TO_EQUATION_RGB;
485   unsigned int indexA   = mBitmask & MASK_EQUATION_ALPHA;
486   indexA                = indexA >> SHIFT_TO_EQUATION_ALPHA;
487
488   return (((indexRgb >= BLENDING_EQUATION_ADVANCED_INDEX_START) && (indexRgb <= BLENDING_EQUATION_ADVANCED_INDEX_END)) ||
489           ((indexA >= BLENDING_EQUATION_ADVANCED_INDEX_START) && (indexA <= BLENDING_EQUATION_ADVANCED_INDEX_END)));
490 }
491
492 bool BlendingOptions::IsAdvancedBlendEquationIncluded(unsigned int bitmask)
493 {
494   unsigned int indexRgb = bitmask & MASK_EQUATION_RGB;
495   indexRgb              = indexRgb >> SHIFT_TO_EQUATION_RGB;
496   unsigned int indexA   = bitmask & MASK_EQUATION_ALPHA;
497   indexA                = indexA >> SHIFT_TO_EQUATION_ALPHA;
498
499   return (((indexRgb >= BLENDING_EQUATION_ADVANCED_INDEX_START) && (indexRgb <= BLENDING_EQUATION_ADVANCED_INDEX_END)) ||
500           ((indexA >= BLENDING_EQUATION_ADVANCED_INDEX_START) && (indexA <= BLENDING_EQUATION_ADVANCED_INDEX_END)));
501 }
502
503 bool BlendingOptions::IsAdvancedBlendEquation(DevelBlendEquation::Type equation)
504 {
505   switch(equation)
506   {
507     case DevelBlendEquation::MULTIPLY:
508     case DevelBlendEquation::SCREEN:
509     case DevelBlendEquation::OVERLAY:
510     case DevelBlendEquation::DARKEN:
511     case DevelBlendEquation::LIGHTEN:
512     case DevelBlendEquation::COLOR_DODGE:
513     case DevelBlendEquation::COLOR_BURN:
514     case DevelBlendEquation::HARD_LIGHT:
515     case DevelBlendEquation::SOFT_LIGHT:
516     case DevelBlendEquation::DIFFERENCE:
517     case DevelBlendEquation::EXCLUSION:
518     case DevelBlendEquation::HUE:
519     case DevelBlendEquation::SATURATION:
520     case DevelBlendEquation::COLOR:
521     case DevelBlendEquation::LUMINOSITY:
522     {
523       return true;
524     }
525
526     default:
527     {
528       return false;
529     }
530   }
531 }
532
533 } // namespace Internal
534
535 } // namespace Dali