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