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 #include "render_pixfmt_rgba_blend.h"
17 
18 namespace OHOS {
Attach(RenderPixfmtRgbaBlend & pixf,int32_t x1,int32_t y1,int32_t x2,int32_t y2)19 bool RenderPixfmtRgbaBlend::Attach(RenderPixfmtRgbaBlend& pixf, int32_t x1, int32_t y1, int32_t x2, int32_t y2)
20 {
21     Rect32 r(x1, y1, x2, y2);
22     if (r.Intersect(r, Rect32(0, 0, pixf.GetWidth() - 1, pixf.GetHeight() - 1))) {
23         int32_t stride = pixf.GetStride();
24         rBuf_->Attach(pixf.PixPtr(r.GetLeft(), stride < 0 ? r.GetBottom() : r.GetTop()),
25                       (r.GetRight() - r.GetLeft()) + 1, (r.GetBottom() - r.GetTop()) + 1, stride);
26         return true;
27     }
28     return false;
29 }
30 
CopyHLine(int32_t x,int32_t y,uint32_t len,const Rgba8T & color)31 void RenderPixfmtRgbaBlend::CopyHLine(int32_t x, int32_t y,
32                                       uint32_t len,
33                                       const Rgba8T& color)
34 {
35     PixelColorType vPixelValue;
36     vPixelValue.SetPixelColor(color);
37     PixelColorType* pixelPtr = PixValuePtr(x, y);
38 #ifdef NEON_ARM_OPT
39     int16_t step = NEON_STEP_8 * PIX_STEP;
40     while (len >= NEON_STEP_8) {
41         SetPixelColor_ARGB8888(pixelPtr->colors, color->red,
42                                colors->green, colors->blue,
43                                colors->alpha);
44         pixelPtr = pixelPtr->colors + step;
45         len -= NEON_STEP_8;
46     };
47 #endif
48     for (uint32_t iPixel = 0; iPixel < len; ++iPixel) {
49         *pixelPtr = vPixelValue;
50         pixelPtr = pixelPtr->Next();
51     }
52 }
53 
BlendHLine(int32_t x,int32_t y,uint32_t len,const Rgba8T & color,uint8_t cover)54 void RenderPixfmtRgbaBlend::BlendHLine(int32_t x, int32_t y,
55                                        uint32_t len,
56                                        const Rgba8T& color,
57                                        uint8_t cover)
58 {
59     if (!color.IsTransparent()) {
60         PixelColorType* pPixel = PixValuePtr(x, y);
61 #ifdef NEON_ARM_OPT
62         int16_t step = NEON_STEP_8 * PIX_STEP;
63         while (len >= NEON_STEP_8) {
64             NeonBlendPix(pixelPtr, color, cover);
65             pixelPtr = pixelPtr->colors + step;
66             len -= NEON_STEP_8;
67         };
68 #endif
69         if (color.IsOpaque() && cover == COVER_MASK) {
70             for (uint32_t iPixel = 0; iPixel < len; ++iPixel) {
71                 PixelColorType pixelValue;
72                 pixelValue.SetPixelColor(color);
73                 *pPixel = pixelValue;
74                 pPixel = pPixel->Next();
75             }
76         } else {
77             if (cover == COVER_MASK) {
78                 for (uint32_t iPixel = 0; iPixel < len; ++iPixel) {
79                     BlendPix(pPixel, color);
80                     pPixel = pPixel->Next();
81                 }
82             } else {
83                 for (uint32_t iPixel = 0; iPixel < len; ++iPixel) {
84                     BlendPix(pPixel, color, cover);
85                     pPixel = pPixel->Next();
86                 }
87             }
88         }
89     }
90 }
91 
BlendSolidHSpan(int32_t x,int32_t y,uint32_t len,const Rgba8T & color,const uint8_t * covers)92 void RenderPixfmtRgbaBlend::BlendSolidHSpan(int32_t x, int32_t y,
93                                             uint32_t len,
94                                             const Rgba8T& color,
95                                             const uint8_t* covers)
96 {
97     if (!color.IsTransparent()) {
98         PixelColorType* pixelPtr = PixValuePtr(x, y);
99 
100 #ifdef NEON_ARM_OPT
101         int16_t step = NEON_STEP_8 * PIX_STEP;
102         while (len >= NEON_STEP_8) {
103             NeonBlendPix(pixelPtr->colors, color, covers);
104             pixelPtr = pixelPtr->colors + step;
105             covers += NEON_STEP_8;
106             len -= NEON_STEP_8;
107         };
108 #endif
109 
110         for (uint32_t iPixel = 0; iPixel < len; ++iPixel) {
111             if (color.IsOpaque() && *covers == COVER_MASK) {
112                 pixelPtr->SetPixelColor(color);
113             } else {
114                 BlendPix(pixelPtr, color, *covers);
115             }
116             pixelPtr = pixelPtr->Next();
117             ++covers;
118         }
119     }
120 }
121 
BlendSolidVSpan(int32_t x,int32_t y,uint32_t len,const Rgba8T & color,const uint8_t * covers)122 void RenderPixfmtRgbaBlend::BlendSolidVSpan(int32_t x, int32_t y,
123                                             uint32_t len,
124                                             const Rgba8T& color,
125                                             const uint8_t* covers)
126 {
127     if (!color.IsTransparent()) {
128         do {
129             PixelColorType* pixelPtr = PixValuePtr(x, y++);
130             if (color.IsOpaque() && *covers == COVER_MASK) {
131                 pixelPtr->SetPixelColor(color);
132             } else {
133                 BlendPix(pixelPtr, color, *covers);
134             }
135             ++covers;
136         } while (--len);
137     }
138 }
139 
CopyColorHSpan(int32_t x,int32_t y,uint32_t len,const Rgba8T * colors)140 void RenderPixfmtRgbaBlend::CopyColorHSpan(int32_t x, int32_t y,
141                                            uint32_t len,
142                                            const Rgba8T* colors)
143 {
144     PixelColorType* pixelPtr = PixValuePtr(x, y);
145 #ifdef NEON_ARM_OPT
146     int16_t step = NEON_STEP_8 * PIX_STEP;
147     const int16_t NEON_STEP_COMPONENTS = NEON_STEP_8 * NUM_COMPONENTS;
148     uint8_t mColors[NEON_STEP_COMPONENTS];
149     while (len >= NEON_STEP_8) {
150         if (memset_s(mColors, size_t(NEON_STEP_COMPONENTS), 0, size_t(NEON_STEP_COMPONENTS)) != EOK) {
151             return GRAPHIC_LOGE("CopyColorHSpan faile");
152         }
153         NeonMemcpy(mColors, NEON_STEP_COMPONENTS, colors, NEON_STEP_COMPONENTS);
154 
155         SetPixelColor_ARGB8888(pixelPtr->colors, mColors);
156         pixelPtr = pixelPtr->colors + step;
157         colors += NEON_STEP_8;
158         len -= NEON_STEP_8;
159     };
160 #endif
161     for (uint32_t iPixel = 0; iPixel < len; ++iPixel) {
162         pixelPtr->SetPixelColor(*colors++);
163         pixelPtr = pixelPtr->Next();
164     }
165 }
166 
CopyColorVSpan(int32_t x,int32_t y,uint32_t len,const Rgba8T * colors)167 void RenderPixfmtRgbaBlend::CopyColorVSpan(int32_t x, int32_t y,
168                                            uint32_t len,
169                                            const Rgba8T* colors)
170 {
171     do {
172         PixValuePtr(x, y++)->SetPixelColor(*colors++);
173     } while (--len);
174 }
175 
BlendColorHSpan(int32_t x,int32_t y,uint32_t len,const Rgba8T * colors,const uint8_t * covers,uint8_t cover)176 void RenderPixfmtRgbaBlend::BlendColorHSpan(int32_t x, int32_t y,
177                                             uint32_t len,
178                                             const Rgba8T* colors,
179                                             const uint8_t* covers,
180                                             uint8_t cover)
181 {
182     PixelColorType* pixelPtr = PixValuePtr(x, y);
183     if (covers) {
184 #ifdef NEON_ARM_OPT
185         int16_t step = NEON_STEP_8 * PIX_STEP;
186         const int16_t NEON_STEP_COMPONENTS = NEON_STEP_8 * NUM_COMPONENTS;
187         uint8_t mColors[NEON_STEP_COMPONENTS];
188         while (len >= NEON_STEP_8) {
189             if (memset_s(mColors, size_t(NEON_STEP_COMPONENTS), 0, size_t(NEON_STEP_COMPONENTS)) != EOK) {
190                 GRAPHIC_LOGE("BlendColorHSpan fail");
191                 return;
192             }
193             NeonMemcpy(mColors, NEON_STEP_COMPONENTS, colors, NEON_STEP_COMPONENTS);
194 
195             NeonBlendPix(pixelPtr->colors, mColors, covers);
196             pixelPtr = pixelPtr->colors + step;
197             colors += NEON_STEP_8;
198             covers += NEON_STEP_8;
199             len -= NEON_STEP_8;
200         };
201 #endif
202         for (uint32_t iPixel = 0; iPixel < len; ++iPixel) {
203             CopyOrBlendPix(pixelPtr, *colors++, *covers++);
204             pixelPtr = pixelPtr->Next();
205         }
206     } else {
207 #ifdef NEON_ARM_OPT
208         int16_t step = NEON_STEP_8 * PIX_STEP;
209         const int16_t NEON_STEP_COMPONENTS = NEON_STEP_8 * NUM_COMPONENTS;
210         uint8_t mColors[NEON_STEP_COMPONENTS];
211         while (len >= NEON_STEP_8) {
212             if (memset_s(mColors, size_t(NEON_STEP_COMPONENTS), 0, size_t(NEON_STEP_COMPONENTS)) != EOK) {
213                 GRAPHIC_LOGE("BlendColorHSpan fail");
214                 return;
215             }
216             NeonMemcpy(mColors, NEON_STEP_COMPONENTS, colors, NEON_STEP_COMPONENTS);
217 
218             NeonBlendPix(pixelPtr->colors, mColors, cover);
219             pixelPtr = pixelPtr->colors + step;
220             colors += NEON_STEP_8;
221             len -= NEON_STEP_8;
222         };
223 #endif
224         if (cover == COVER_MASK) {
225             for (uint32_t iPixel = 0; iPixel < len; ++iPixel) {
226                 cover == COVER_MASK ? CopyOrBlendPix(pixelPtr, *colors++) :
227                                       CopyOrBlendPix(pixelPtr, *colors++, cover);
228                 pixelPtr = pixelPtr->Next();
229             }
230         }
231     }
232 }
233 } // namespace OHOS
234