/* * Copyright (c) 2022 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "render_pixfmt_rgba_blend.h" namespace OHOS { bool RenderPixfmtRgbaBlend::Attach(RenderPixfmtRgbaBlend& pixf, int32_t x1, int32_t y1, int32_t x2, int32_t y2) { Rect32 r(x1, y1, x2, y2); if (r.Intersect(r, Rect32(0, 0, pixf.GetWidth() - 1, pixf.GetHeight() - 1))) { int32_t stride = pixf.GetStride(); rBuf_->Attach(pixf.PixPtr(r.GetLeft(), stride < 0 ? r.GetBottom() : r.GetTop()), (r.GetRight() - r.GetLeft()) + 1, (r.GetBottom() - r.GetTop()) + 1, stride); return true; } return false; } void RenderPixfmtRgbaBlend::CopyHLine(int32_t x, int32_t y, uint32_t len, const Rgba8T& color) { PixelColorType vPixelValue; vPixelValue.SetPixelColor(color); PixelColorType* pixelPtr = PixValuePtr(x, y); #ifdef NEON_ARM_OPT int16_t step = NEON_STEP_8 * PIX_STEP; while (len >= NEON_STEP_8) { SetPixelColor_ARGB8888(pixelPtr->colors, color->red, colors->green, colors->blue, colors->alpha); pixelPtr = pixelPtr->colors + step; len -= NEON_STEP_8; }; #endif for (uint32_t iPixel = 0; iPixel < len; ++iPixel) { *pixelPtr = vPixelValue; pixelPtr = pixelPtr->Next(); } } void RenderPixfmtRgbaBlend::BlendHLine(int32_t x, int32_t y, uint32_t len, const Rgba8T& color, uint8_t cover) { if (!color.IsTransparent()) { PixelColorType* pPixel = PixValuePtr(x, y); #ifdef NEON_ARM_OPT int16_t step = NEON_STEP_8 * PIX_STEP; while (len >= NEON_STEP_8) { NeonBlendPix(pixelPtr, color, cover); pixelPtr = pixelPtr->colors + step; len -= NEON_STEP_8; }; #endif if (color.IsOpaque() && cover == COVER_MASK) { for (uint32_t iPixel = 0; iPixel < len; ++iPixel) { PixelColorType pixelValue; pixelValue.SetPixelColor(color); *pPixel = pixelValue; pPixel = pPixel->Next(); } } else { if (cover == COVER_MASK) { for (uint32_t iPixel = 0; iPixel < len; ++iPixel) { BlendPix(pPixel, color); pPixel = pPixel->Next(); } } else { for (uint32_t iPixel = 0; iPixel < len; ++iPixel) { BlendPix(pPixel, color, cover); pPixel = pPixel->Next(); } } } } } void RenderPixfmtRgbaBlend::BlendSolidHSpan(int32_t x, int32_t y, uint32_t len, const Rgba8T& color, const uint8_t* covers) { if (!color.IsTransparent()) { PixelColorType* pixelPtr = PixValuePtr(x, y); #ifdef NEON_ARM_OPT int16_t step = NEON_STEP_8 * PIX_STEP; while (len >= NEON_STEP_8) { NeonBlendPix(pixelPtr->colors, color, covers); pixelPtr = pixelPtr->colors + step; covers += NEON_STEP_8; len -= NEON_STEP_8; }; #endif for (uint32_t iPixel = 0; iPixel < len; ++iPixel) { if (color.IsOpaque() && *covers == COVER_MASK) { pixelPtr->SetPixelColor(color); } else { BlendPix(pixelPtr, color, *covers); } pixelPtr = pixelPtr->Next(); ++covers; } } } void RenderPixfmtRgbaBlend::BlendSolidVSpan(int32_t x, int32_t y, uint32_t len, const Rgba8T& color, const uint8_t* covers) { if (!color.IsTransparent()) { do { PixelColorType* pixelPtr = PixValuePtr(x, y++); if (color.IsOpaque() && *covers == COVER_MASK) { pixelPtr->SetPixelColor(color); } else { BlendPix(pixelPtr, color, *covers); } ++covers; } while (--len); } } void RenderPixfmtRgbaBlend::CopyColorHSpan(int32_t x, int32_t y, uint32_t len, const Rgba8T* colors) { PixelColorType* pixelPtr = PixValuePtr(x, y); #ifdef NEON_ARM_OPT int16_t step = NEON_STEP_8 * PIX_STEP; const int16_t NEON_STEP_COMPONENTS = NEON_STEP_8 * NUM_COMPONENTS; uint8_t mColors[NEON_STEP_COMPONENTS]; while (len >= NEON_STEP_8) { if (memset_s(mColors, size_t(NEON_STEP_COMPONENTS), 0, size_t(NEON_STEP_COMPONENTS)) != EOK) { return GRAPHIC_LOGE("CopyColorHSpan faile"); } NeonMemcpy(mColors, NEON_STEP_COMPONENTS, colors, NEON_STEP_COMPONENTS); SetPixelColor_ARGB8888(pixelPtr->colors, mColors); pixelPtr = pixelPtr->colors + step; colors += NEON_STEP_8; len -= NEON_STEP_8; }; #endif for (uint32_t iPixel = 0; iPixel < len; ++iPixel) { pixelPtr->SetPixelColor(*colors++); pixelPtr = pixelPtr->Next(); } } void RenderPixfmtRgbaBlend::CopyColorVSpan(int32_t x, int32_t y, uint32_t len, const Rgba8T* colors) { do { PixValuePtr(x, y++)->SetPixelColor(*colors++); } while (--len); } void RenderPixfmtRgbaBlend::BlendColorHSpan(int32_t x, int32_t y, uint32_t len, const Rgba8T* colors, const uint8_t* covers, uint8_t cover) { PixelColorType* pixelPtr = PixValuePtr(x, y); if (covers) { #ifdef NEON_ARM_OPT int16_t step = NEON_STEP_8 * PIX_STEP; const int16_t NEON_STEP_COMPONENTS = NEON_STEP_8 * NUM_COMPONENTS; uint8_t mColors[NEON_STEP_COMPONENTS]; while (len >= NEON_STEP_8) { if (memset_s(mColors, size_t(NEON_STEP_COMPONENTS), 0, size_t(NEON_STEP_COMPONENTS)) != EOK) { GRAPHIC_LOGE("BlendColorHSpan fail"); return; } NeonMemcpy(mColors, NEON_STEP_COMPONENTS, colors, NEON_STEP_COMPONENTS); NeonBlendPix(pixelPtr->colors, mColors, covers); pixelPtr = pixelPtr->colors + step; colors += NEON_STEP_8; covers += NEON_STEP_8; len -= NEON_STEP_8; }; #endif for (uint32_t iPixel = 0; iPixel < len; ++iPixel) { CopyOrBlendPix(pixelPtr, *colors++, *covers++); pixelPtr = pixelPtr->Next(); } } else { #ifdef NEON_ARM_OPT int16_t step = NEON_STEP_8 * PIX_STEP; const int16_t NEON_STEP_COMPONENTS = NEON_STEP_8 * NUM_COMPONENTS; uint8_t mColors[NEON_STEP_COMPONENTS]; while (len >= NEON_STEP_8) { if (memset_s(mColors, size_t(NEON_STEP_COMPONENTS), 0, size_t(NEON_STEP_COMPONENTS)) != EOK) { GRAPHIC_LOGE("BlendColorHSpan fail"); return; } NeonMemcpy(mColors, NEON_STEP_COMPONENTS, colors, NEON_STEP_COMPONENTS); NeonBlendPix(pixelPtr->colors, mColors, cover); pixelPtr = pixelPtr->colors + step; colors += NEON_STEP_8; len -= NEON_STEP_8; }; #endif if (cover == COVER_MASK) { for (uint32_t iPixel = 0; iPixel < len; ++iPixel) { cover == COVER_MASK ? CopyOrBlendPix(pixelPtr, *colors++) : CopyOrBlendPix(pixelPtr, *colors++, cover); pixelPtr = pixelPtr->Next(); } } } } } // namespace OHOS