1 /* 2 * Copyright (c) 2022 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef GRAPHIC_LITE_RENDER_PIXFMT_RGBA_BLEND_H 17 #define GRAPHIC_LITE_RENDER_PIXFMT_RGBA_BLEND_H 18 19 #include "draw/draw_utils.h" 20 #include "engines/gfx/gfx_engine_manager.h" 21 #include "gfx_utils/heap_base.h" 22 #include "gfx_utils/graphic_log.h" 23 #include "render/render_buffer.h" 24 25 #ifdef ARM_NEON_OPT 26 #include "graphic_neon_pipeline.h" 27 #endif 28 namespace OHOS { 29 const uint8_t NUM_COMPONENTS = 4; 30 const uint8_t PIX_STEP = 4; 31 32 struct RgbaBlender { 33 #ifdef ARM_NEON_OPT 34 /** 35 * @brief Mix the pixels with the color component. 36 * @param color color,red,green,blue,alpha Color Component,cover Coverage. 37 * @since 1.0 38 * @version 1.0 39 */ NeonBlendPixRgbaBlender40 static inline void NeonBlendPix( 41 uint8_t* color, uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha, uint8_t* covers) 42 { 43 DrawUtils::GetInstance()->BlendLerpPix(color, red, green, blue, alpha, covers); 44 } 45 46 /** 47 * @brief Mix the pixels with the color component. 48 * @param color color,red,green,blue,alpha Color Component,cover Coverage. 49 * @since 1.0 50 * @version 1.0 51 */ NeonBlendPixRgbaBlender52 static inline void NeonBlendPix( 53 uint8_t* color, uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha, uint8_t cover) 54 { 55 DrawUtils::GetInstance()->BlendLerpPix(color, red, green, blue, alpha, cover); 56 } 57 58 /** 59 * @brief Mix the pixels with the color component. 60 * @param color color,red,green,blue,alpha Color Component 61 * @since 1.0 62 * @version 1.0 63 */ NeonBlendPixRgbaBlender64 static inline void NeonBlendPix( 65 uint8_t* color, uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha) 66 { 67 DrawUtils::GetInstance()->BlendLerpPix(color, red, green, blue, alpha); 68 } 69 NeonBlendPixRgbaBlender70 static inline void NeonBlendPix(uint8_t* dstColors, uint8_t* srcColors, uint8_t srcCover) 71 { 72 DrawUtils::GetInstance()->BlendLerpPix(dstColors, srcColors, srcCover); 73 } 74 NeonBlendPixRgbaBlender75 static inline void NeonBlendPix(uint8_t* dstColors, uint8_t* srcColors, uint8_t* srcCovers) 76 { 77 DrawUtils::GetInstance()->BlendLerpPix(dstColors, srcColors, srcCovers); 78 } 79 #endif 80 /** 81 * @brief Mix the pixels with the color component. 82 * @param color color,red,green,blue,alpha Color Component,cover Coverage. 83 * @since 1.0 84 * @version 1.0 85 */ BlendPixRgbaBlender86 static inline void BlendPix( 87 uint8_t* color, uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha, uint8_t cover) 88 { 89 BlendPix(color, red, green, blue, Rgba8T::MultCover(alpha, cover)); 90 } 91 92 /** 93 * @brief Mix the pixels with the color component. 94 * @param color color,red,green,blue,alpha Color Component 95 * @since 1.0 96 * @version 1.0 97 */ BlendPixRgbaBlender98 static inline void BlendPix( 99 uint8_t* color, uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha) 100 { 101 color[OrderBgra::RED] = Rgba8T::Lerp(color[OrderBgra::RED], red, alpha); 102 color[OrderBgra::GREEN] = Rgba8T::Lerp(color[OrderBgra::GREEN], green, alpha); 103 color[OrderBgra::BLUE] = Rgba8T::Lerp(color[OrderBgra::BLUE], blue, alpha); 104 color[OrderBgra::ALPHA] = Rgba8T::Prelerp(color[OrderBgra::ALPHA], alpha, alpha); 105 } 106 }; 107 108 struct PixelColorType { 109 uint8_t colors[NUM_COMPONENTS]; 110 111 /** 112 * @brief Set Colors. 113 * @param r,g,b,a Color Component. 114 * @since 1.0 115 * @version 1.0 116 */ SetPixelColorPixelColorType117 void SetPixelColor(uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha) 118 { 119 colors[OrderBgra::RED] = red; 120 colors[OrderBgra::GREEN] = green; 121 colors[OrderBgra::BLUE] = blue; 122 colors[OrderBgra::ALPHA] = alpha; 123 } 124 125 /** 126 * @brief Set Colors. 127 * @param color Colors. 128 * @since 1.0 129 * @version 1.0 130 */ SetPixelColorPixelColorType131 void SetPixelColor(const Rgba8T& color) 132 { 133 SetPixelColor(color.red, color.green, color.blue, color.alpha); 134 } 135 136 /** 137 * @brief Get Colors. 138 * @param r,g,b,a Color Component. 139 * @since 1.0 140 * @version 1.0 141 */ GetPixelColorPixelColorType142 void GetPixelColor(uint8_t& red, uint8_t& green, uint8_t& blue, uint8_t& alpha) const 143 { 144 red = colors[OrderBgra::RED]; 145 green = colors[OrderBgra::GREEN]; 146 blue = colors[OrderBgra::BLUE]; 147 alpha = colors[OrderBgra::ALPHA]; 148 } 149 150 /** 151 * @brief Get Colors. 152 * @return Colors 153 * @since 1.0 154 * @version 1.0 155 */ GetPixelColorPixelColorType156 Rgba8T GetPixelColor() const 157 { 158 return Rgba8T(colors[OrderBgra::RED], colors[OrderBgra::GREEN], 159 colors[OrderBgra::BLUE], colors[OrderBgra::ALPHA]); 160 } 161 162 /** 163 * @brief Gets the color component of the next pixel. 164 * 165 * @since 1.0 166 * @version 1.0 167 */ NextPixelColorType168 PixelColorType* Next() 169 { 170 return reinterpret_cast<PixelColorType*>((colors + PIX_STEP)); 171 } 172 173 /** 174 * @brief Gets the first address of the color component of the next pixel. 175 * 176 * @since 1.0 177 * @version 1.0 178 */ NextPixelColorType179 const PixelColorType* Next() const 180 { 181 return reinterpret_cast<const PixelColorType*>(colors + PIX_STEP); 182 } 183 184 /** 185 * @brief Gets the first address of the color component of the nth pixe. 186 * @param pixelIndex pixel offset 187 * @since 1.0 188 * @version 1.0 189 */ AdvancePixelColorType190 PixelColorType* Advance(int32_t pixelIndex) 191 { 192 return reinterpret_cast<PixelColorType*>(colors + pixelIndex * PIX_STEP); 193 } 194 195 /** 196 * @brief Gets the first address of the color component of the nth pixe. 197 * @param pixelIndex pixel offset 198 * @since 1.0 199 * @version 1.0 200 */ AdvancePixelColorType201 const PixelColorType* Advance(int32_t pixelIndex) const 202 { 203 return reinterpret_cast<const PixelColorType*>(colors + pixelIndex * PIX_STEP); 204 } 205 }; 206 207 class RenderPixfmtRgbaBlend : public HeapBase { 208 public: 209 const uint8_t PIX_WIDTH = sizeof(uint8_t) * PIX_STEP; RenderPixfmtRgbaBlend()210 RenderPixfmtRgbaBlend() : rBuf_(0) {} RenderPixfmtRgbaBlend(RenderBuffer & rBuf)211 explicit RenderPixfmtRgbaBlend(RenderBuffer& rBuf) : rBuf_(&rBuf) {} 212 213 /** 214 * @brief Attach pixels to the drawing area. 215 * 216 * @since 1.0 217 * @version 1.0 218 */ Attach(RenderBuffer & rBuf)219 virtual void Attach(RenderBuffer& rBuf) 220 { 221 rBuf_ = &rBuf; 222 } 223 224 bool Attach(RenderPixfmtRgbaBlend& pixf, int32_t x1, int32_t y1, int32_t x2, int32_t y2); 225 226 /** 227 * @brief Get the size of each screen (draw buffer). 228 * 229 * @since 1.0 230 * @version 1.0 231 */ GetWidth()232 virtual inline uint32_t GetWidth() const 233 { 234 return rBuf_->GetWidth(); 235 } 236 GetHeight()237 virtual inline uint32_t GetHeight() const 238 { 239 return rBuf_->GetHeight(); 240 } 241 242 /** 243 * @brief Returns the number of bytes in a row of the window. 244 * 245 * @since 1.0 246 * @version 1.0 247 */ GetStride()248 virtual inline int32_t GetStride() const 249 { 250 return rBuf_->GetStride(); 251 } 252 253 /** 254 * @brief Returns the row address of a window row. 255 * 256 * @since 1.0 257 * @version 1.0 258 */ GetRowPtr(int32_t y)259 virtual inline uint8_t* GetRowPtr(int32_t y) 260 { 261 return rBuf_->GetRowPtr(y); 262 } 263 264 /** 265 * @brief Returns the row address of a window row. 266 * 267 * @since 1.0 268 * @version 1.0 269 */ GetRowPtr(int32_t y)270 virtual inline const uint8_t* GetRowPtr(int32_t y) const 271 { 272 return rBuf_->GetRowPtr(y); 273 } 274 275 /** 276 * @brief Returns the row data of one row of the window. 277 * 278 * @since 1.0 279 * @version 1.0 280 */ GetRow(int32_t y)281 virtual inline RowData GetRow(int32_t y) const 282 { 283 return rBuf_->GetRow(y); 284 } 285 PixPtr(int32_t x,int32_t y)286 virtual inline uint8_t* PixPtr(int32_t x, int32_t y) 287 { 288 return rBuf_->GetRowPtr(y) + sizeof(uint8_t) * (x * PIX_STEP); 289 } 290 PixPtr(int32_t x,int32_t y)291 virtual inline const uint8_t* PixPtr(int32_t x, int32_t y) const 292 { 293 return rBuf_->GetRowPtr(y) + sizeof(uint8_t) * (x * PIX_STEP); 294 } 295 296 /** 297 * @brief Pointer to pixel type pointer. 298 * 299 * @since 1.0 300 * @version 1.0 301 */ PixValuePtr(int32_t x,int32_t y)302 virtual inline PixelColorType* PixValuePtr(int32_t x, int32_t y) 303 { 304 return reinterpret_cast<PixelColorType*>(rBuf_->GetRowPtr(y) + sizeof(uint8_t) * (x * PIX_STEP)); 305 } 306 307 /** 308 * @brief Gets the pixel address of the specified left. 309 * 310 * @since 1.0 311 * @version 1.0. 312 */ PixValuePtr(int32_t x,int32_t y)313 virtual inline const PixelColorType* PixValuePtr(int32_t x, int32_t y) const 314 { 315 uint8_t* pixelPtr = rBuf_->GetRowPtr(y); 316 return pixelPtr ? reinterpret_cast<PixelColorType*>(pixelPtr + sizeof(uint8_t) * (x * PIX_STEP)) : nullptr; 317 } 318 319 /** 320 * @brief Pointer to pixel type pointer. 321 * 322 * @since 1.0 323 * @version 1.0 324 */ PixValuePtr(void * pixelPtr)325 inline static PixelColorType* PixValuePtr(void* pixelPtr) 326 { 327 return static_cast<PixelColorType*>(pixelPtr); 328 } 329 330 /** 331 * @brief Pointer to pixel type pointer. 332 * 333 * @since 1.0 334 * @version 1.0 335 */ PixValuePtr(const void * pixelPtr)336 inline static const PixelColorType* PixValuePtr(const void* pixelPtr) 337 { 338 return static_cast<const PixelColorType*>(pixelPtr); 339 } 340 341 /** 342 * @brief Gets the color of a pixel. 343 * 344 * @since 1.0 345 * @version 1.0 346 */ Pixel(int32_t x,int32_t y)347 virtual inline Rgba8T Pixel(int32_t x, int32_t y) const 348 { 349 const PixelColorType* pixelPtr = PixValuePtr(x, y); 350 if (pixelPtr != nullptr) { 351 return pixelPtr->GetPixelColor(); 352 } 353 return Rgba8T::NoColor(); 354 } 355 356 /** 357 * @brief Copy color to pixel. 358 * 359 * @since 1.0 360 * @version 1.0 361 */ CopyPixel(int32_t x,int32_t y,const Rgba8T & color)362 virtual inline void CopyPixel(int32_t x, int32_t y, const Rgba8T& color) 363 { 364 PixValuePtr(x, y)->SetPixelColor(color); 365 } 366 367 /** 368 * @brief Mix pixels (x, y) with the transparency of cover (coverage = transparency) with color color. 369 * 370 * @since 1.0 371 * @version 1.0 372 */ BlendPixel(int32_t x,int32_t y,const Rgba8T & color,uint8_t cover)373 virtual inline void BlendPixel(int32_t x, int32_t y, const Rgba8T& color, uint8_t cover) 374 { 375 CopyOrBlendPix(PixValuePtr(x, y), color, cover); 376 } 377 378 /** 379 * @brief Set the pixels of len length in horizontal order starting from (x, y). 380 * 381 * @since 1.0 382 * @version 1.0 383 */ 384 virtual void CopyHLine(int32_t x, int32_t y, 385 uint32_t len, 386 const Rgba8T& color); 387 388 /** 389 * @brief Pixels of len length are mixed horizontally from (x, y). 390 * 391 * @since 1.0 392 * @version 1.0 393 */ 394 virtual void BlendHLine(int32_t x, int32_t y, 395 uint32_t len, 396 const Rgba8T& color, 397 uint8_t cover); 398 399 /** 400 * @brief Mix a series of colors of len length in horizontal order starting from (x, y). 401 * 402 * @since 1.0 403 * @version 1.0 404 */ 405 virtual void BlendSolidHSpan(int32_t x, int32_t y, 406 uint32_t len, 407 const Rgba8T& color, 408 const uint8_t* covers); 409 410 /** 411 * @brief Mix a series of colors of len length in vertical order starting from (x, y). 412 * 413 * @since 1.0 414 * @version 1.0 415 */ 416 virtual void BlendSolidVSpan(int32_t x, int32_t y, 417 uint32_t len, 418 const Rgba8T& color, 419 const uint8_t* covers); 420 421 /** 422 * @brief Set the color of len length in horizontal order starting from (x, y). 423 * 424 * @since 1.0 425 * @version 1.0 426 */ 427 virtual void CopyColorHSpan(int32_t x, int32_t y, 428 uint32_t len, 429 const Rgba8T* colors); 430 431 /** 432 * @brief Set the color of len length in vertical order starting from (x, y). 433 * 434 * @since 1.0 435 * @version 1.0 436 */ 437 virtual void CopyColorVSpan(int32_t x, int32_t y, 438 uint32_t len, 439 const Rgba8T* colors); 440 441 /** 442 * @brief Mix a series of colors of len length in horizontal order starting from (x, y). 443 * @param x x coordinate. 444 * @param y x coordinate 445 * @param len length of line 446 * @param colors colors array 447 * @param covers transition value 448 * @param cover cover value 449 * @since 1.0 450 * @version 1.0 451 */ 452 void BlendColorHSpan(int32_t x, int32_t y, 453 uint32_t len, 454 const Rgba8T* colors, 455 const uint8_t* covers, 456 uint8_t cover); 457 458 protected: 459 #ifdef ARM_NEON_OPT NeonBlendPix(PixelColorType * pixelColors,const Rgba8T & color)460 virtual inline void NeonBlendPix(PixelColorType* pixelColors, const Rgba8T& color) 461 { 462 blender_.NeonBlendPix(pixelColors->colors, color.red, color.green, 463 color.blue, color.alpha); 464 } 465 NeonBlendPix(PixelColorType * pixelColors,const Rgba8T & color,uint8_t cover)466 virtual inline void NeonBlendPix(PixelColorType* pixelColors, const Rgba8T& color, uint8_t cover) 467 { 468 blender_.NeonBlendPix(pixelColors->colors, color.red, color.green, 469 color.blue, color.alpha, cover); 470 } 471 NeonBlendPix(uint8_t * dstColors,uint8_t * srcColors,uint8_t srcCover)472 virtual inline void NeonBlendPix(uint8_t* dstColors, uint8_t* srcColors, uint8_t srcCover) 473 { 474 blender_.NeonBlendPix(dstColors, srcColors, srcCover); 475 } 476 NeonBlendPix(uint8_t * dstColors,uint8_t * srcColors,uint8_t * srcCovers)477 virtual inline void NeonBlendPix(uint8_t* dstColors, uint8_t* srcColors, uint8_t* srcCovers) 478 { 479 blender_.NeonBlendPix(dstColors, srcColors, srcCovers); 480 } 481 NeonBlendPix(uint8_t * dstColors,const Rgba8T & srcColors,uint8_t * srcCovers)482 virtual inline void NeonBlendPix(uint8_t* dstColors, const Rgba8T& srcColors, uint8_t* srcCovers) 483 { 484 blender_.NeonBlendPix(dstColors, srcColors.red, srcColors.green, srcColors.blue, 485 srcColors.alpha, srcCovers); 486 } 487 #endif 488 489 /** 490 * @brief Blend color and coverage to specified pixels. 491 * 492 * @since 1.0 493 * @version 1.0 494 */ BlendPix(PixelColorType * pixelPtr,const Rgba8T & color,uint32_t cover)495 virtual inline void BlendPix(PixelColorType* pixelPtr, const Rgba8T& color, uint32_t cover) 496 { 497 blender_.BlendPix(pixelPtr->colors, color.red, color.green, color.blue, color.alpha, cover); 498 } 499 500 /** 501 * @brief Blend colors to specified pixels. 502 * 503 * @since 1.0 504 * @version 1.0 505 */ BlendPix(PixelColorType * pixelPtr,const Rgba8T & color)506 virtual inline void BlendPix(PixelColorType* pixelPtr, const Rgba8T& color) 507 { 508 blender_.BlendPix(pixelPtr->colors, color.red, color.green, color.blue, color.alpha); 509 } 510 511 /** 512 * @brief Set or blend to specified pixels with color and coverage. 513 * 514 * @since 1.0 515 * @version 1.0 516 */ CopyOrBlendPix(PixelColorType * pixelPtr,const Rgba8T & color,uint32_t cover)517 virtual inline void CopyOrBlendPix(PixelColorType* pixelPtr, const Rgba8T& color, uint32_t cover) 518 { 519 if (!color.IsTransparent()) { 520 if (color.IsOpaque() && cover == COVER_MASK) { 521 pixelPtr->SetPixelColor(color.red, color.green, color.blue, color.alpha); 522 } else { 523 blender_.BlendPix(pixelPtr->colors, color.red, color.green, 524 color.blue, color.alpha, cover); 525 } 526 } 527 } 528 529 /** 530 * @brief Sets or blends the color to the specified pixel. 531 * 532 * @since 1.0 533 * @version 1.0. 534 */ CopyOrBlendPix(PixelColorType * pixelPtr,const Rgba8T & color)535 virtual inline void CopyOrBlendPix(PixelColorType* pixelPtr, const Rgba8T& color) 536 { 537 if (!color.IsTransparent()) { 538 if (color.IsOpaque()) { 539 pixelPtr->SetPixelColor(color); 540 } else { 541 blender_.BlendPix(pixelPtr->colors, color.red, color.green, 542 color.blue, color.alpha); 543 } 544 } 545 } 546 547 RenderBuffer* rBuf_; 548 RgbaBlender blender_; 549 }; 550 } // namespace OHOS 551 #endif 552