2 * Copyright (c) 2021 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 <dali/internal/common/blending-options.h>
21 namespace // unnamed namespace
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;
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;
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
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.
48 void StoreBlendFactor(unsigned int& options, BlendFactor::Type factor, int bitShift)
52 case BlendFactor::ZERO:
54 options |= (0u << bitShift);
58 case BlendFactor::ONE:
60 options |= (1u << bitShift);
64 case BlendFactor::SRC_COLOR:
66 options |= (2u << bitShift);
70 case BlendFactor::ONE_MINUS_SRC_COLOR:
72 options |= (3u << bitShift);
76 case BlendFactor::SRC_ALPHA:
78 options |= (4u << bitShift);
82 case BlendFactor::ONE_MINUS_SRC_ALPHA:
84 options |= (5u << bitShift);
88 case BlendFactor::DST_ALPHA:
90 options |= (6u << bitShift);
94 case BlendFactor::ONE_MINUS_DST_ALPHA:
96 options |= (7u << bitShift);
100 case BlendFactor::DST_COLOR:
102 options |= (8u << bitShift);
106 case BlendFactor::ONE_MINUS_DST_COLOR:
108 options |= (9u << bitShift);
112 case BlendFactor::SRC_ALPHA_SATURATE:
114 options |= (10u << bitShift);
118 case BlendFactor::CONSTANT_COLOR:
120 options |= (11u << bitShift);
124 case BlendFactor::ONE_MINUS_CONSTANT_COLOR:
126 options |= (12u << bitShift);
130 case BlendFactor::CONSTANT_ALPHA:
132 options |= (13u << bitShift);
136 case BlendFactor::ONE_MINUS_CONSTANT_ALPHA:
138 options |= (14u << bitShift);
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.
150 void StoreBlendEquation(unsigned int& options, DevelBlendEquation::Type factor, int bitShift)
152 // Must be same order as BLENDING_EQUATIONS, below:
157 REVERSE_SUBTRACT_BITVAL,
179 case DevelBlendEquation::ADD:
181 options |= (ADD_BITVAL << bitShift);
185 case DevelBlendEquation::SUBTRACT:
187 options |= (SUBTRACT_BITVAL << bitShift);
191 case DevelBlendEquation::REVERSE_SUBTRACT:
193 options |= (REVERSE_SUBTRACT_BITVAL << bitShift);
197 case DevelBlendEquation::MIN:
199 options |= (MIN_BITVAL << bitShift);
203 case DevelBlendEquation::MAX:
205 options |= (MAX_BITVAL << bitShift);
209 case DevelBlendEquation::MULTIPLY:
211 options |= (MULTIPLY_BITVAL << bitShift);
215 case DevelBlendEquation::SCREEN:
217 options |= (SCREEN_BITVAL << bitShift);
221 case DevelBlendEquation::OVERLAY:
223 options |= (OVERLAY_BITVAL << bitShift);
227 case DevelBlendEquation::DARKEN:
229 options |= (DARKEN_BITVAL << bitShift);
233 case DevelBlendEquation::LIGHTEN:
235 options |= (LIGHTEN_BITVAL << bitShift);
239 case DevelBlendEquation::COLOR_DODGE:
241 options |= (COLOR_DODGE_BITVAL << bitShift);
245 case DevelBlendEquation::COLOR_BURN:
247 options |= (COLOR_BURN_BITVAL << bitShift);
251 case DevelBlendEquation::HARD_LIGHT:
253 options |= (HARD_LIGHT_BITVAL << bitShift);
257 case DevelBlendEquation::SOFT_LIGHT:
259 options |= (SOFT_LIGHT_BITVAL << bitShift);
263 case DevelBlendEquation::DIFFERENCE:
265 options |= (DIFFERENCE_BITVAL << bitShift);
269 case DevelBlendEquation::EXCLUSION:
271 options |= (EXCLUSION_BITVAL << bitShift);
275 case DevelBlendEquation::HUE:
277 options |= (HUE_BITVAL << bitShift);
281 case DevelBlendEquation::SATURATION:
283 options |= (SATURATION_BITVAL << bitShift);
287 case DevelBlendEquation::COLOR:
289 options |= (COLOR_BITVAL << bitShift);
293 case DevelBlendEquation::LUMINOSITY:
295 options |= (LUMINOSITY_BITVAL << bitShift);
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;
306 BlendFactor::Type BLENDING_FACTORS[BLENDING_FACTOR_COUNT] =
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};
324 DevelBlendEquation::Type BLENDING_EQUATIONS[BLENDING_EQUATION_COUNT] =
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};
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.
354 BlendFactor::Type RetrieveBlendFactor(unsigned int options, int mask, int bitShift)
356 unsigned int index = options & mask;
357 index = index >> bitShift;
359 DALI_ASSERT_DEBUG(index < BLENDING_FACTOR_COUNT);
361 return BLENDING_FACTORS[index];
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.
371 DevelBlendEquation::Type RetrieveBlendEquation(unsigned int options, int mask, int bitShift)
373 unsigned int index = options & mask;
374 index = index >> bitShift;
376 DALI_ASSERT_DEBUG(index < BLENDING_EQUATION_COUNT);
378 return BLENDING_EQUATIONS[index];
381 } // unnamed namespace
387 BlendingOptions::BlendingOptions()
391 SetBlendFunc(BlendFactor::SRC_ALPHA, BlendFactor::ONE_MINUS_SRC_ALPHA, BlendFactor::ONE, BlendFactor::ONE_MINUS_SRC_ALPHA);
393 SetBlendEquation(DevelBlendEquation::ADD, DevelBlendEquation::ADD);
396 BlendingOptions::~BlendingOptions() = default;
398 void BlendingOptions::SetBitmask(unsigned int bitmask)
403 unsigned int BlendingOptions::GetBitmask() const
408 void BlendingOptions::SetBlendFunc(BlendFactor::Type srcFactorRgb, BlendFactor::Type destFactorRgb, BlendFactor::Type srcFactorAlpha, BlendFactor::Type destFactorAlpha)
410 mBitmask &= CLEAR_BLEND_FUNC_MASK; // Clear the BlendFunc values
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);
418 BlendFactor::Type BlendingOptions::GetBlendSrcFactorRgb() const
420 return RetrieveBlendFactor(mBitmask, MASK_SRC_FACTOR_RGB, SHIFT_TO_SRC_FACTOR_RGB);
423 BlendFactor::Type BlendingOptions::GetBlendDestFactorRgb() const
425 return RetrieveBlendFactor(mBitmask, MASK_DEST_FACTOR_RGB, SHIFT_TO_DEST_FACTOR_RGB);
428 BlendFactor::Type BlendingOptions::GetBlendSrcFactorAlpha() const
430 return RetrieveBlendFactor(mBitmask, MASK_SRC_FACTOR_ALPHA, SHIFT_TO_SRC_FACTOR_ALPHA);
433 BlendFactor::Type BlendingOptions::GetBlendDestFactorAlpha() const
435 return RetrieveBlendFactor(mBitmask, MASK_DEST_FACTOR_ALPHA, SHIFT_TO_DEST_FACTOR_ALPHA);
438 void BlendingOptions::SetBlendEquation(DevelBlendEquation::Type equationRgb, DevelBlendEquation::Type equationAlpha)
440 mBitmask &= CLEAR_BLEND_EQUATION_MASK; // Clear the BlendEquation values
442 StoreBlendEquation(mBitmask, equationRgb, SHIFT_TO_EQUATION_RGB);
443 StoreBlendEquation(mBitmask, equationAlpha, SHIFT_TO_EQUATION_ALPHA);
446 DevelBlendEquation::Type BlendingOptions::GetBlendEquationRgb() const
448 return RetrieveBlendEquation(mBitmask, MASK_EQUATION_RGB, SHIFT_TO_EQUATION_RGB);
451 DevelBlendEquation::Type BlendingOptions::GetBlendEquationAlpha() const
453 return RetrieveBlendEquation(mBitmask, MASK_EQUATION_ALPHA, SHIFT_TO_EQUATION_ALPHA);
456 void BlendingOptions::SetBlendColor(const Vector4& color)
458 if(Color::TRANSPARENT == color)
460 mBlendColor = nullptr;
466 *mBlendColor = color;
470 // Lazy allocation when non-default is set
471 mBlendColor = new Vector4(color);
476 const Vector4* BlendingOptions::GetBlendColor() const
478 return mBlendColor.Get();
481 bool BlendingOptions::IsAdvancedBlendEquationApplied()
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;
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)));
492 bool BlendingOptions::IsAdvancedBlendEquationIncluded(unsigned int bitmask)
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;
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)));
503 bool BlendingOptions::IsAdvancedBlendEquation(DevelBlendEquation::Type equation)
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:
533 } // namespace Internal