1bafb9395Sopenharmony_ci/*
2bafb9395Sopenharmony_ci * Copyright (c) 2020-2022 Huawei Device Co., Ltd.
3bafb9395Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4bafb9395Sopenharmony_ci * you may not use this file except in compliance with the License.
5bafb9395Sopenharmony_ci * You may obtain a copy of the License at
6bafb9395Sopenharmony_ci *
7bafb9395Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8bafb9395Sopenharmony_ci *
9bafb9395Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10bafb9395Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11bafb9395Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12bafb9395Sopenharmony_ci * See the License for the specific language governing permissions and
13bafb9395Sopenharmony_ci * limitations under the License.
14bafb9395Sopenharmony_ci */
15bafb9395Sopenharmony_ci
16bafb9395Sopenharmony_ci#ifndef GRAPHIC_LITE_GRAPHIC_NEON_PIPELINE_H
17bafb9395Sopenharmony_ci#define GRAPHIC_LITE_GRAPHIC_NEON_PIPELINE_H
18bafb9395Sopenharmony_ci
19bafb9395Sopenharmony_ci#include "graphic_config.h"
20bafb9395Sopenharmony_ci#ifdef ARM_NEON_OPT
21bafb9395Sopenharmony_ci#include <arm_neon.h>
22bafb9395Sopenharmony_ci
23bafb9395Sopenharmony_ci#include "gfx_utils/color.h"
24bafb9395Sopenharmony_ci#include "graphic_neon_utils.h"
25bafb9395Sopenharmony_ci
26bafb9395Sopenharmony_cinamespace OHOS {
27bafb9395Sopenharmony_ciusing LoadBuf = void (*)(uint8_t* buf, uint8x8_t& r, uint8x8_t& g, uint8x8_t& b, uint8x8_t& a);
28bafb9395Sopenharmony_ciusing LoadBufA = void (*)(uint8_t* buf, uint8x8_t& r, uint8x8_t& g, uint8x8_t& b, uint8x8_t& a, uint8_t opa);
29bafb9395Sopenharmony_ciusing NeonBlend = void (*)(uint8x8_t& r1, uint8x8_t& g1, uint8x8_t& b1, uint8x8_t& a1,
30bafb9395Sopenharmony_ci                           uint8x8_t r2, uint8x8_t g2, uint8x8_t b2, uint8x8_t a2);
31bafb9395Sopenharmony_ciusing StoreBuf = void (*)(uint8_t* buf, uint8x8_t& r, uint8x8_t& g, uint8x8_t& b, uint8x8_t& a);
32bafb9395Sopenharmony_ci
33bafb9395Sopenharmony_cistruct {
34bafb9395Sopenharmony_ci    ColorMode dm;
35bafb9395Sopenharmony_ci    LoadBuf loadDstFunc;
36bafb9395Sopenharmony_ci    NeonBlend blendFunc;
37bafb9395Sopenharmony_ci    StoreBuf storeDstFunc;
38bafb9395Sopenharmony_ci}
39bafb9395Sopenharmony_cig_dstFunc[] = {
40bafb9395Sopenharmony_ci    {ARGB8888, LoadBuf_ARGB8888, NeonBlendRGBA, StoreBuf_ARGB8888},
41bafb9395Sopenharmony_ci    {XRGB8888, LoadBuf_XRGB8888, NeonBlendXRGB, StoreBuf_XRGB8888},
42bafb9395Sopenharmony_ci    {RGB888, LoadBuf_RGB888, NeonBlendRGB, StoreBuf_RGB888},
43bafb9395Sopenharmony_ci    {RGB565, LoadBuf_RGB565, NeonBlendRGB, StoreBuf_RGB565}
44bafb9395Sopenharmony_ci};
45bafb9395Sopenharmony_ci
46bafb9395Sopenharmony_cistruct {
47bafb9395Sopenharmony_ci    ColorMode sm;
48bafb9395Sopenharmony_ci    LoadBufA loadSrcFunc;
49bafb9395Sopenharmony_ci}
50bafb9395Sopenharmony_cig_srcFunc[] = {
51bafb9395Sopenharmony_ci    {ARGB8888, LoadBufA_ARGB8888},
52bafb9395Sopenharmony_ci    {XRGB8888, LoadBufA_XRGB8888},
53bafb9395Sopenharmony_ci    {RGB888, LoadBufA_RGB888},
54bafb9395Sopenharmony_ci    {RGB565, LoadBufA_RGB565}
55bafb9395Sopenharmony_ci};
56bafb9395Sopenharmony_ci
57bafb9395Sopenharmony_ciclass NeonBlendPipeLine {
58bafb9395Sopenharmony_cipublic:
59bafb9395Sopenharmony_ci    NeonBlendPipeLine() {}
60bafb9395Sopenharmony_ci    ~NeonBlendPipeLine() {}
61bafb9395Sopenharmony_ci
62bafb9395Sopenharmony_ci    void Construct(ColorMode dm, ColorMode sm, void* srcColor = nullptr, uint8_t opa = OPA_OPAQUE)
63bafb9395Sopenharmony_ci    {
64bafb9395Sopenharmony_ci        int16_t dstNum = sizeof(g_dstFunc) / sizeof(g_dstFunc[0]);
65bafb9395Sopenharmony_ci        for (int16_t i = 0; i < dstNum; ++i) {
66bafb9395Sopenharmony_ci            if (g_dstFunc[i].dm == dm) {
67bafb9395Sopenharmony_ci                loadDstFunc_ = g_dstFunc[i].loadDstFunc;
68bafb9395Sopenharmony_ci                blendFunc_ = g_dstFunc[i].blendFunc;
69bafb9395Sopenharmony_ci                storeDstFunc_ = g_dstFunc[i].storeDstFunc;
70bafb9395Sopenharmony_ci                break;
71bafb9395Sopenharmony_ci            }
72bafb9395Sopenharmony_ci        }
73bafb9395Sopenharmony_ci        int16_t srcNum = sizeof(g_srcFunc) / sizeof(g_srcFunc[0]);
74bafb9395Sopenharmony_ci        for (int16_t i = 0; i < srcNum; ++i) {
75bafb9395Sopenharmony_ci            if (g_srcFunc[i].sm == sm) {
76bafb9395Sopenharmony_ci                loadSrcFunc_ = g_srcFunc[i].loadSrcFunc;
77bafb9395Sopenharmony_ci                break;
78bafb9395Sopenharmony_ci            }
79bafb9395Sopenharmony_ci        }
80bafb9395Sopenharmony_ci        if (srcColor != nullptr) {
81bafb9395Sopenharmony_ci            ConstructSrcColor(sm, srcColor, opa, r2_, g2_, b2_, a2_);
82bafb9395Sopenharmony_ci        }
83bafb9395Sopenharmony_ci    }
84bafb9395Sopenharmony_ci
85bafb9395Sopenharmony_ci    void Invoke(uint8_t* dst, uint8_t* src, uint8_t opa)
86bafb9395Sopenharmony_ci    {
87bafb9395Sopenharmony_ci        loadDstFunc_(dst, r1_, g1_, b1_, a1_);
88bafb9395Sopenharmony_ci        loadSrcFunc_(src, r2_, g2_, b2_, a2_, opa);
89bafb9395Sopenharmony_ci        blendFunc_(r1_, g1_, b1_, a1_, r2_, g2_, b2_, a2_);
90bafb9395Sopenharmony_ci        storeDstFunc_(dst, r1_, g1_, b1_, a1_);
91bafb9395Sopenharmony_ci    }
92bafb9395Sopenharmony_ci
93bafb9395Sopenharmony_ci    void Invoke(uint8_t* dst)
94bafb9395Sopenharmony_ci    {
95bafb9395Sopenharmony_ci        loadDstFunc_(dst, r1_, g1_, b1_, a1_);
96bafb9395Sopenharmony_ci        blendFunc_(r1_, g1_, b1_, a1_, r2_, g2_, b2_, a2_);
97bafb9395Sopenharmony_ci        storeDstFunc_(dst, r1_, g1_, b1_, a1_);
98bafb9395Sopenharmony_ci    }
99bafb9395Sopenharmony_ci
100bafb9395Sopenharmony_ci    void Invoke(uint8_t* dst, uint8x8_t& r, uint8x8_t& g, uint8x8_t& b, uint8x8_t& a)
101bafb9395Sopenharmony_ci    {
102bafb9395Sopenharmony_ci        loadDstFunc_(dst, r1_, g1_, b1_, a1_);
103bafb9395Sopenharmony_ci        blendFunc_(r1_, g1_, b1_, a1_, r, g, b, a);
104bafb9395Sopenharmony_ci        storeDstFunc_(dst, r1_, g1_, b1_, a1_);
105bafb9395Sopenharmony_ci    }
106bafb9395Sopenharmony_ci
107bafb9395Sopenharmony_ci    void NeonPreLerpARGB8888(uint8_t* buf, uint8_t r, uint8_t g, uint8_t b, uint8_t a, uint8_t* covers)
108bafb9395Sopenharmony_ci    {
109bafb9395Sopenharmony_ci        uint8x8x4_t vBuf = vld4_u8(buf);
110bafb9395Sopenharmony_ci        uint8x8_t r0 = vBuf.val[NEON_R];
111bafb9395Sopenharmony_ci        uint8x8_t g0 = vBuf.val[NEON_G];
112bafb9395Sopenharmony_ci        uint8x8_t b0 = vBuf.val[NEON_B];
113bafb9395Sopenharmony_ci        uint8x8_t a0 = vBuf.val[NEON_A];
114bafb9395Sopenharmony_ci
115bafb9395Sopenharmony_ci        uint8x8_t r1 = Multipling(vdup_n_u8(r), vld1_u8(covers));
116bafb9395Sopenharmony_ci        uint8x8_t g1 = Multipling(vdup_n_u8(g), vld1_u8(covers));
117bafb9395Sopenharmony_ci        uint8x8_t b1 = Multipling(vdup_n_u8(b), vld1_u8(covers));
118bafb9395Sopenharmony_ci        uint8x8_t a1 = Multipling(vdup_n_u8(a), vld1_u8(covers));
119bafb9395Sopenharmony_ci
120bafb9395Sopenharmony_ci        uint8x8_t rs = NeonLerp(r0, r1, a1);
121bafb9395Sopenharmony_ci        uint8x8_t gs = NeonLerp(g0, g1, a1);
122bafb9395Sopenharmony_ci        uint8x8_t bs = NeonLerp(b0, b1, a1);
123bafb9395Sopenharmony_ci        uint8x8_t as = NeonPreLerp(a0, a1, a1);
124bafb9395Sopenharmony_ci
125bafb9395Sopenharmony_ci        StoreBuf_ARGB8888(buf, rs, gs, bs, as);
126bafb9395Sopenharmony_ci    }
127bafb9395Sopenharmony_ci    void NeonPrelerpARGB8888(uint8_t* buf, uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha)
128bafb9395Sopenharmony_ci    {
129bafb9395Sopenharmony_ci        uint8x8x4_t vBuf = vld4_u8(buf);
130bafb9395Sopenharmony_ci        uint8x8_t r0 = vBuf.val[NEON_R];
131bafb9395Sopenharmony_ci        uint8x8_t g0 = vBuf.val[NEON_G];
132bafb9395Sopenharmony_ci        uint8x8_t b0 = vBuf.val[NEON_B];
133bafb9395Sopenharmony_ci        uint8x8_t a0 = vBuf.val[NEON_A];
134bafb9395Sopenharmony_ci
135bafb9395Sopenharmony_ci        uint8x8_t r1 = vdup_n_u8(red);
136bafb9395Sopenharmony_ci        uint8x8_t g1 = vdup_n_u8(green);
137bafb9395Sopenharmony_ci        uint8x8_t b1 = vdup_n_u8(blue);
138bafb9395Sopenharmony_ci        uint8x8_t a1 = vdup_n_u8(alpha);
139bafb9395Sopenharmony_ci
140bafb9395Sopenharmony_ci        uint8x8_t rs = NeonPreLerp(r0, r1, a1);
141bafb9395Sopenharmony_ci        uint8x8_t gs = NeonPreLerp(g0, g1, a1);
142bafb9395Sopenharmony_ci        uint8x8_t bs = NeonPreLerp(b0, b1, a1);
143bafb9395Sopenharmony_ci        uint8x8_t as = NeonPreLerp(a0, a1, a1);
144bafb9395Sopenharmony_ci
145bafb9395Sopenharmony_ci        StoreBuf_ARGB8888(buf, rs, gs, bs, as);
146bafb9395Sopenharmony_ci    }
147bafb9395Sopenharmony_ci
148bafb9395Sopenharmony_ci    void NeonPrelerpARGB8888(uint8_t* buf, uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha, uint8_t cover)
149bafb9395Sopenharmony_ci    {
150bafb9395Sopenharmony_ci        uint8x8x4_t vBuf = vld4_u8(buf);
151bafb9395Sopenharmony_ci        uint8x8_t r0 = vBuf.val[NEON_R];
152bafb9395Sopenharmony_ci        uint8x8_t g0 = vBuf.val[NEON_G];
153bafb9395Sopenharmony_ci        uint8x8_t b0 = vBuf.val[NEON_B];
154bafb9395Sopenharmony_ci        uint8x8_t a0 = vBuf.val[NEON_A];
155bafb9395Sopenharmony_ci
156bafb9395Sopenharmony_ci        uint8x8_t r1 = Multipling(vdup_n_u8(red), vdup_n_u8(cover));
157bafb9395Sopenharmony_ci        uint8x8_t g1 = Multipling(vdup_n_u8(green), vdup_n_u8(cover));
158bafb9395Sopenharmony_ci        uint8x8_t b1 = Multipling(vdup_n_u8(blue), vdup_n_u8(cover));
159bafb9395Sopenharmony_ci        uint8x8_t a1 = Multipling(vdup_n_u8(alpha), vdup_n_u8(cover));
160bafb9395Sopenharmony_ci
161bafb9395Sopenharmony_ci        uint8x8_t rs = NeonPreLerp(r0, r1, a1);
162bafb9395Sopenharmony_ci        uint8x8_t gs = NeonPreLerp(g0, g1, a1);
163bafb9395Sopenharmony_ci        uint8x8_t bs = NeonPreLerp(b0, b1, a1);
164bafb9395Sopenharmony_ci        uint8x8_t as = NeonPreLerp(a0, a1, a1);
165bafb9395Sopenharmony_ci
166bafb9395Sopenharmony_ci        StoreBuf_ARGB8888(buf, rs, gs, bs, as);
167bafb9395Sopenharmony_ci    }
168bafb9395Sopenharmony_ci
169bafb9395Sopenharmony_ci    void NeonPrelerpARGB8888(uint8_t* dstBuffer, uint8_t* srcBuffer, uint8_t cover)
170bafb9395Sopenharmony_ci    {
171bafb9395Sopenharmony_ci        uint8x8x4_t vDstBuf = vld4_u8(dstBuffer);
172bafb9395Sopenharmony_ci        uint8x8_t r0 = vDstBuf.val[NEON_R];
173bafb9395Sopenharmony_ci        uint8x8_t g0 = vDstBuf.val[NEON_G];
174bafb9395Sopenharmony_ci        uint8x8_t b0 = vDstBuf.val[NEON_B];
175bafb9395Sopenharmony_ci        uint8x8_t a0 = vDstBuf.val[NEON_A];
176bafb9395Sopenharmony_ci        uint8x8x4_t vSrcBuf = vld4_u8(srcBuffer);
177bafb9395Sopenharmony_ci        uint8x8_t r1 = vSrcBuf.val[NEON_R];
178bafb9395Sopenharmony_ci        uint8x8_t g1 = vSrcBuf.val[NEON_G];
179bafb9395Sopenharmony_ci        uint8x8_t b1 = vSrcBuf.val[NEON_B];
180bafb9395Sopenharmony_ci        uint8x8_t a1 = vSrcBuf.val[NEON_A];
181bafb9395Sopenharmony_ci
182bafb9395Sopenharmony_ci        r1 = Multipling(r1, vdup_n_u8(cover));
183bafb9395Sopenharmony_ci        g1 = Multipling(g1, vdup_n_u8(cover));
184bafb9395Sopenharmony_ci        b1 = Multipling(b1, vdup_n_u8(cover));
185bafb9395Sopenharmony_ci        a1 = Multipling(a1, vdup_n_u8(cover));
186bafb9395Sopenharmony_ci
187bafb9395Sopenharmony_ci        uint8x8_t rs = NeonPreLerp(r0, r1, a1);
188bafb9395Sopenharmony_ci        uint8x8_t gs = NeonPreLerp(g0, g1, a1);
189bafb9395Sopenharmony_ci        uint8x8_t bs = NeonPreLerp(b0, b1, a1);
190bafb9395Sopenharmony_ci        uint8x8_t as = NeonPreLerp(a0, a1, a1);
191bafb9395Sopenharmony_ci
192bafb9395Sopenharmony_ci        StoreBuf_ARGB8888(dstBuffer, rs, gs, bs, as);
193bafb9395Sopenharmony_ci    }
194bafb9395Sopenharmony_ci
195bafb9395Sopenharmony_ci    void NeonPrelerpARGB8888(uint8_t* dstBuffer, uint8_t* srcBuffer, uint8_t* covers)
196bafb9395Sopenharmony_ci    {
197bafb9395Sopenharmony_ci        uint8x8x4_t vDstBuf = vld4_u8(dstBuffer);
198bafb9395Sopenharmony_ci        uint8x8_t r0 = vDstBuf.val[NEON_R];
199bafb9395Sopenharmony_ci        uint8x8_t g0 = vDstBuf.val[NEON_G];
200bafb9395Sopenharmony_ci        uint8x8_t b0 = vDstBuf.val[NEON_B];
201bafb9395Sopenharmony_ci        uint8x8_t a0 = vDstBuf.val[NEON_A];
202bafb9395Sopenharmony_ci
203bafb9395Sopenharmony_ci        uint8x8x4_t vSrcBuf = vld4_u8(srcBuffer);
204bafb9395Sopenharmony_ci
205bafb9395Sopenharmony_ci        uint8x8_t r1 = Multipling(vSrcBuf.val[NEON_R], vld1_u8(covers));
206bafb9395Sopenharmony_ci        uint8x8_t g1 = Multipling(vSrcBuf.val[NEON_G], vld1_u8(covers));
207bafb9395Sopenharmony_ci        uint8x8_t b1 = Multipling(vSrcBuf.val[NEON_B], vld1_u8(covers));
208bafb9395Sopenharmony_ci        uint8x8_t a1 = Multipling(vSrcBuf.val[NEON_A], vld1_u8(covers));
209bafb9395Sopenharmony_ci
210bafb9395Sopenharmony_ci        uint8x8_t rs = NeonPreLerp(r0, r1, a1);
211bafb9395Sopenharmony_ci        uint8x8_t gs = NeonPreLerp(g0, g1, a1);
212bafb9395Sopenharmony_ci        uint8x8_t bs = NeonPreLerp(b0, b1, a1);
213bafb9395Sopenharmony_ci        uint8x8_t as = NeonPreLerp(a0, a1, a1);
214bafb9395Sopenharmony_ci
215bafb9395Sopenharmony_ci        StoreBuf_ARGB8888(dstBuffer, rs, gs, bs, as);
216bafb9395Sopenharmony_ci    }
217bafb9395Sopenharmony_ci    void NeonLerpARGB8888(uint8_t* buf, uint8_t r, uint8_t g, uint8_t b, uint8_t a,
218bafb9395Sopenharmony_ci                           uint8_t* covers)
219bafb9395Sopenharmony_ci    {
220bafb9395Sopenharmony_ci        uint8x8x4_t vBuf = vld4_u8(buf);
221bafb9395Sopenharmony_ci        uint8x8_t r0 = vBuf.val[NEON_R];
222bafb9395Sopenharmony_ci        uint8x8_t g0 = vBuf.val[NEON_G];
223bafb9395Sopenharmony_ci        uint8x8_t b0 = vBuf.val[NEON_B];
224bafb9395Sopenharmony_ci        uint8x8_t a0 = vBuf.val[NEON_A];
225bafb9395Sopenharmony_ci
226bafb9395Sopenharmony_ci        uint8x8_t r1 = Multipling(vdup_n_u8(r), vld1_u8(covers));
227bafb9395Sopenharmony_ci        uint8x8_t g1 = Multipling(vdup_n_u8(g), vld1_u8(covers));
228bafb9395Sopenharmony_ci        uint8x8_t b1 = Multipling(vdup_n_u8(b), vld1_u8(covers));
229bafb9395Sopenharmony_ci        uint8x8_t a1 = Multipling(vdup_n_u8(a), vld1_u8(covers));
230bafb9395Sopenharmony_ci
231bafb9395Sopenharmony_ci        uint8x8_t rs = NeonLerp(r0, r1, a1);
232bafb9395Sopenharmony_ci        uint8x8_t gs = NeonLerp(g0, g1, a1);
233bafb9395Sopenharmony_ci        uint8x8_t bs = NeonLerp(b0, b1, a1);
234bafb9395Sopenharmony_ci        uint8x8_t as = NeonPreLerp(a0, a1, a1);
235bafb9395Sopenharmony_ci
236bafb9395Sopenharmony_ci        StoreBuf_ARGB8888(buf, rs, gs, bs, as);
237bafb9395Sopenharmony_ci    }
238bafb9395Sopenharmony_ci    void NeonLerpARGB8888(uint8_t* buf, uint8_t r, uint8_t g, uint8_t b, uint8_t a)
239bafb9395Sopenharmony_ci    {
240bafb9395Sopenharmony_ci        uint8x8x4_t vBuf = vld4_u8(buf);
241bafb9395Sopenharmony_ci        uint8x8_t r0 = vBuf.val[NEON_R];
242bafb9395Sopenharmony_ci        uint8x8_t g0 = vBuf.val[NEON_G];
243bafb9395Sopenharmony_ci        uint8x8_t b0 = vBuf.val[NEON_B];
244bafb9395Sopenharmony_ci        uint8x8_t a0 = vBuf.val[NEON_A];
245bafb9395Sopenharmony_ci
246bafb9395Sopenharmony_ci        uint8x8_t r1 = vdup_n_u8(r);
247bafb9395Sopenharmony_ci        uint8x8_t g1 = vdup_n_u8(g);
248bafb9395Sopenharmony_ci        uint8x8_t b1 = vdup_n_u8(b);
249bafb9395Sopenharmony_ci        uint8x8_t a1 = vdup_n_u8(a);
250bafb9395Sopenharmony_ci
251bafb9395Sopenharmony_ci        uint8x8_t rs = NeonLerp(r0, r1, a1);
252bafb9395Sopenharmony_ci        uint8x8_t gs = NeonLerp(g0, g1, a1);
253bafb9395Sopenharmony_ci        uint8x8_t bs = NeonLerp(b0, b1, a1);
254bafb9395Sopenharmony_ci        uint8x8_t as = NeonPreLerp(a0, a1, a1);
255bafb9395Sopenharmony_ci
256bafb9395Sopenharmony_ci        StoreBuf_ARGB8888(buf, rs, gs, bs, as);
257bafb9395Sopenharmony_ci    }
258bafb9395Sopenharmony_ci
259bafb9395Sopenharmony_ci    void NeonLerpARGB8888(uint8_t* buf, uint8_t r, uint8_t g, uint8_t b, uint8_t a, uint8_t cover)
260bafb9395Sopenharmony_ci    {
261bafb9395Sopenharmony_ci        uint8x8x4_t vBuf = vld4_u8(buf);
262bafb9395Sopenharmony_ci        uint8x8_t r0 = vBuf.val[NEON_R];
263bafb9395Sopenharmony_ci        uint8x8_t g0 = vBuf.val[NEON_G];
264bafb9395Sopenharmony_ci        uint8x8_t b0 = vBuf.val[NEON_B];
265bafb9395Sopenharmony_ci        uint8x8_t a0 = vBuf.val[NEON_A];
266bafb9395Sopenharmony_ci
267bafb9395Sopenharmony_ci        uint8x8_t r1 = Multipling(vdup_n_u8(r), vdup_n_u8(cover));
268bafb9395Sopenharmony_ci        uint8x8_t g1 = Multipling(vdup_n_u8(g), vdup_n_u8(cover));
269bafb9395Sopenharmony_ci        uint8x8_t b1 = Multipling(vdup_n_u8(b), vdup_n_u8(cover));
270bafb9395Sopenharmony_ci        uint8x8_t a1 = Multipling(vdup_n_u8(a), vdup_n_u8(cover));
271bafb9395Sopenharmony_ci
272bafb9395Sopenharmony_ci        uint8x8_t rs = NeonLerp(r0, r1, a1);
273bafb9395Sopenharmony_ci        uint8x8_t gs = NeonLerp(g0, g1, a1);
274bafb9395Sopenharmony_ci        uint8x8_t bs = NeonLerp(b0, b1, a1);
275bafb9395Sopenharmony_ci        uint8x8_t as = NeonPreLerp(a0, a1, a1);
276bafb9395Sopenharmony_ci
277bafb9395Sopenharmony_ci        StoreBuf_ARGB8888(buf, rs, gs, bs, as);
278bafb9395Sopenharmony_ci    }
279bafb9395Sopenharmony_ci
280bafb9395Sopenharmony_ci    void NeonLerpARGB8888(uint8_t* dstBuffer, uint8_t* srcBuffer, uint8_t cover)
281bafb9395Sopenharmony_ci    {
282bafb9395Sopenharmony_ci        uint8x8x4_t vDstBuf = vld4_u8(dstBuffer);
283bafb9395Sopenharmony_ci        uint8x8_t r0 = vDstBuf.val[NEON_R];
284bafb9395Sopenharmony_ci        uint8x8_t g0 = vDstBuf.val[NEON_G];
285bafb9395Sopenharmony_ci        uint8x8_t b0 = vDstBuf.val[NEON_B];
286bafb9395Sopenharmony_ci        uint8x8_t a0 = vDstBuf.val[NEON_A];
287bafb9395Sopenharmony_ci        uint8x8x4_t vSrcBuf = vld4_u8(srcBuffer);
288bafb9395Sopenharmony_ci        uint8x8_t r1 = vSrcBuf.val[NEON_R];
289bafb9395Sopenharmony_ci        uint8x8_t g1 = vSrcBuf.val[NEON_G];
290bafb9395Sopenharmony_ci        uint8x8_t b1 = vSrcBuf.val[NEON_B];
291bafb9395Sopenharmony_ci        uint8x8_t a1 = vSrcBuf.val[NEON_A];
292bafb9395Sopenharmony_ci
293bafb9395Sopenharmony_ci        r1 = Multipling(r1, vdup_n_u8(cover));
294bafb9395Sopenharmony_ci        g1 = Multipling(g1, vdup_n_u8(cover));
295bafb9395Sopenharmony_ci        b1 = Multipling(b1, vdup_n_u8(cover));
296bafb9395Sopenharmony_ci        a1 = Multipling(a1, vdup_n_u8(cover));
297bafb9395Sopenharmony_ci
298bafb9395Sopenharmony_ci        uint8x8_t rs = NeonLerp(r0, r1, a1);
299bafb9395Sopenharmony_ci        uint8x8_t gs = NeonLerp(g0, g1, a1);
300bafb9395Sopenharmony_ci        uint8x8_t bs = NeonLerp(b0, b1, a1);
301bafb9395Sopenharmony_ci        uint8x8_t as = NeonPreLerp(a0, a1, a1);
302bafb9395Sopenharmony_ci
303bafb9395Sopenharmony_ci        StoreBuf_ARGB8888(dstBuffer, rs, gs, bs, as);
304bafb9395Sopenharmony_ci    }
305bafb9395Sopenharmony_ci
306bafb9395Sopenharmony_ci    void NeonLerpARGB8888(uint8_t* dstBuffer, uint8_t* srcBuffer, uint8_t* covers)
307bafb9395Sopenharmony_ci    {
308bafb9395Sopenharmony_ci        uint8x8x4_t vDstBuf = vld4_u8(dstBuffer);
309bafb9395Sopenharmony_ci        uint8x8_t r0 = vDstBuf.val[NEON_R];
310bafb9395Sopenharmony_ci        uint8x8_t g0 = vDstBuf.val[NEON_G];
311bafb9395Sopenharmony_ci        uint8x8_t b0 = vDstBuf.val[NEON_B];
312bafb9395Sopenharmony_ci        uint8x8_t a0 = vDstBuf.val[NEON_A];
313bafb9395Sopenharmony_ci
314bafb9395Sopenharmony_ci        uint8x8x4_t vSrcBuf = vld4_u8(srcBuffer);
315bafb9395Sopenharmony_ci
316bafb9395Sopenharmony_ci        uint8x8_t r1 = Multipling(vSrcBuf.val[NEON_R], vld1_u8(covers));
317bafb9395Sopenharmony_ci        uint8x8_t g1 = Multipling(vSrcBuf.val[NEON_G], vld1_u8(covers));
318bafb9395Sopenharmony_ci        uint8x8_t b1 = Multipling(vSrcBuf.val[NEON_B], vld1_u8(covers));
319bafb9395Sopenharmony_ci        uint8x8_t a1 = Multipling(vSrcBuf.val[NEON_A], vld1_u8(covers));
320bafb9395Sopenharmony_ci
321bafb9395Sopenharmony_ci        uint8x8_t rs = NeonLerp(r0, r1, a1);
322bafb9395Sopenharmony_ci        uint8x8_t gs = NeonLerp(g0, g1, a1);
323bafb9395Sopenharmony_ci        uint8x8_t bs = NeonLerp(b0, b1, a1);
324bafb9395Sopenharmony_ci        uint8x8_t as = NeonPreLerp(a0, a1, a1);
325bafb9395Sopenharmony_ci
326bafb9395Sopenharmony_ci        StoreBuf_ARGB8888(dstBuffer, rs, gs, bs, as);
327bafb9395Sopenharmony_ci    }
328bafb9395Sopenharmony_ciprivate:
329bafb9395Sopenharmony_ci    void ConstructSrcColor(ColorMode sm, void* srcColor, uint8_t opa,
330bafb9395Sopenharmony_ci                           uint8x8_t& r, uint8x8_t& g, uint8x8_t& b, uint8x8_t& a)
331bafb9395Sopenharmony_ci    {
332bafb9395Sopenharmony_ci        if (sm == ARGB8888) {
333bafb9395Sopenharmony_ci            Color32* color = reinterpret_cast<Color32*>(srcColor);
334bafb9395Sopenharmony_ci            r = vdup_n_u8(color->red);
335bafb9395Sopenharmony_ci            g = vdup_n_u8(color->green);
336bafb9395Sopenharmony_ci            b = vdup_n_u8(color->blue);
337bafb9395Sopenharmony_ci            a = NeonMulDiv255(vdup_n_u8(opa), vdup_n_u8(color->alpha));
338bafb9395Sopenharmony_ci        } else if (sm == XRGB8888) {
339bafb9395Sopenharmony_ci            Color32* color = reinterpret_cast<Color32*>(srcColor);
340bafb9395Sopenharmony_ci            r = vdup_n_u8(color->red);
341bafb9395Sopenharmony_ci            g = vdup_n_u8(color->green);
342bafb9395Sopenharmony_ci            b = vdup_n_u8(color->blue);
343bafb9395Sopenharmony_ci            a = vdup_n_u8(opa);
344bafb9395Sopenharmony_ci        } else if (sm == RGB888) {
345bafb9395Sopenharmony_ci            Color24* color = reinterpret_cast<Color24*>(srcColor);
346bafb9395Sopenharmony_ci            r = vdup_n_u8(color->red);
347bafb9395Sopenharmony_ci            g = vdup_n_u8(color->green);
348bafb9395Sopenharmony_ci            b = vdup_n_u8(color->blue);
349bafb9395Sopenharmony_ci            a = vdup_n_u8(opa);
350bafb9395Sopenharmony_ci        } else if (sm == RGB565) {
351bafb9395Sopenharmony_ci            Color16* color = reinterpret_cast<Color16*>(srcColor);
352bafb9395Sopenharmony_ci            r = vdup_n_u8(color->red);
353bafb9395Sopenharmony_ci            g = vdup_n_u8(color->green);
354bafb9395Sopenharmony_ci            b = vdup_n_u8(color->blue);
355bafb9395Sopenharmony_ci            a = vdup_n_u8(opa);
356bafb9395Sopenharmony_ci        }
357bafb9395Sopenharmony_ci    }
358bafb9395Sopenharmony_ci
359bafb9395Sopenharmony_ci    LoadBuf loadDstFunc_ = nullptr;
360bafb9395Sopenharmony_ci    LoadBufA loadSrcFunc_ = nullptr;
361bafb9395Sopenharmony_ci    NeonBlend blendFunc_ = nullptr;
362bafb9395Sopenharmony_ci    StoreBuf storeDstFunc_ = nullptr;
363bafb9395Sopenharmony_ci    uint8x8_t r1_;
364bafb9395Sopenharmony_ci    uint8x8_t g1_;
365bafb9395Sopenharmony_ci    uint8x8_t b1_;
366bafb9395Sopenharmony_ci    uint8x8_t a1_;
367bafb9395Sopenharmony_ci    uint8x8_t r2_;
368bafb9395Sopenharmony_ci    uint8x8_t g2_;
369bafb9395Sopenharmony_ci    uint8x8_t b2_;
370bafb9395Sopenharmony_ci    uint8x8_t a2_;
371bafb9395Sopenharmony_ci};
372bafb9395Sopenharmony_ci} // namespace OHOS
373bafb9395Sopenharmony_ci#endif
374bafb9395Sopenharmony_ci#endif
375