Loading libs/hwui/FontRenderer.cpp +13 −11 Original line number Original line Diff line number Diff line Loading @@ -592,7 +592,7 @@ void FontRenderer::setFont(const SkPaint* paint, const mat4& matrix) { } } FontRenderer::DropShadow FontRenderer::renderDropShadow(const SkPaint* paint, const char *text, FontRenderer::DropShadow FontRenderer::renderDropShadow(const SkPaint* paint, const char *text, uint32_t startIndex, uint32_t len, int numGlyphs, uint32_t radius, const float* positions) { uint32_t startIndex, uint32_t len, int numGlyphs, float radius, const float* positions) { checkInit(); checkInit(); DropShadow image; DropShadow image; Loading @@ -613,8 +613,9 @@ FontRenderer::DropShadow FontRenderer::renderDropShadow(const SkPaint* paint, co Rect bounds; Rect bounds; mCurrentFont->measure(paint, text, startIndex, len, numGlyphs, &bounds, positions); mCurrentFont->measure(paint, text, startIndex, len, numGlyphs, &bounds, positions); uint32_t paddedWidth = (uint32_t) (bounds.right - bounds.left) + 2 * radius; uint32_t intRadius = Blur::convertRadiusToInt(radius); uint32_t paddedHeight = (uint32_t) (bounds.top - bounds.bottom) + 2 * radius; uint32_t paddedWidth = (uint32_t) (bounds.right - bounds.left) + 2 * intRadius; uint32_t paddedHeight = (uint32_t) (bounds.top - bounds.bottom) + 2 * intRadius; uint32_t maxSize = Caches::getInstance().maxTextureSize; uint32_t maxSize = Caches::getInstance().maxTextureSize; if (paddedWidth > maxSize || paddedHeight > maxSize) { if (paddedWidth > maxSize || paddedHeight > maxSize) { Loading @@ -635,8 +636,8 @@ FontRenderer::DropShadow FontRenderer::renderDropShadow(const SkPaint* paint, co memset(dataBuffer, 0, size); memset(dataBuffer, 0, size); int penX = radius - bounds.left; int penX = intRadius - bounds.left; int penY = radius - bounds.bottom; int penY = intRadius - bounds.bottom; if ((bounds.right > bounds.left) && (bounds.top > bounds.bottom)) { if ((bounds.right > bounds.left) && (bounds.top > bounds.bottom)) { // text has non-whitespace, so draw and blur to create the shadow // text has non-whitespace, so draw and blur to create the shadow Loading Loading @@ -727,9 +728,10 @@ void FontRenderer::removeFont(const Font* font) { } } } } void FontRenderer::blurImage(uint8_t** image, int32_t width, int32_t height, int32_t radius) { void FontRenderer::blurImage(uint8_t** image, int32_t width, int32_t height, float radius) { uint32_t intRadius = Blur::convertRadiusToInt(radius); #ifdef ANDROID_ENABLE_RENDERSCRIPT #ifdef ANDROID_ENABLE_RENDERSCRIPT if (width * height * radius >= RS_MIN_INPUT_CUTOFF) { if (width * height * intRadius >= RS_MIN_INPUT_CUTOFF) { uint8_t* outImage = (uint8_t*) memalign(RS_CPU_ALLOCATION_ALIGNMENT, width * height); uint8_t* outImage = (uint8_t*) memalign(RS_CPU_ALLOCATION_ALIGNMENT, width * height); if (mRs == 0) { if (mRs == 0) { Loading Loading @@ -768,12 +770,12 @@ void FontRenderer::blurImage(uint8_t** image, int32_t width, int32_t height, int } } #endif #endif float *gaussian = new float[2 * radius + 1]; float *gaussian = new float[2 * intRadius + 1]; Blur::generateGaussianWeights(gaussian, radius); Blur::generateGaussianWeights(gaussian, intRadius); uint8_t* scratch = new uint8_t[width * height]; uint8_t* scratch = new uint8_t[width * height]; Blur::horizontal(gaussian, radius, *image, scratch, width, height); Blur::horizontal(gaussian, intRadius, *image, scratch, width, height); Blur::vertical(gaussian, radius, scratch, *image, width, height); Blur::vertical(gaussian, intRadius, scratch, *image, width, height); delete[] gaussian; delete[] gaussian; delete[] scratch; delete[] scratch; Loading libs/hwui/FontRenderer.h +2 −2 Original line number Original line Diff line number Diff line Loading @@ -129,7 +129,7 @@ public: // After renderDropShadow returns, the called owns the memory in DropShadow.image // After renderDropShadow returns, the called owns the memory in DropShadow.image // and is responsible for releasing it when it's done with it // and is responsible for releasing it when it's done with it DropShadow renderDropShadow(const SkPaint* paint, const char *text, uint32_t startIndex, DropShadow renderDropShadow(const SkPaint* paint, const char *text, uint32_t startIndex, uint32_t len, int numGlyphs, uint32_t radius, const float* positions); uint32_t len, int numGlyphs, float radius, const float* positions); void setTextureFiltering(bool linearFiltering) { void setTextureFiltering(bool linearFiltering) { mLinearFiltering = linearFiltering; mLinearFiltering = linearFiltering; Loading Loading @@ -218,7 +218,7 @@ private: int32_t width, int32_t height); int32_t width, int32_t height); // the input image handle may have its pointer replaced (to avoid copies) // the input image handle may have its pointer replaced (to avoid copies) void blurImage(uint8_t** image, int32_t width, int32_t height, int32_t radius); void blurImage(uint8_t** image, int32_t width, int32_t height, float radius); }; }; }; // namespace uirenderer }; // namespace uirenderer Loading libs/hwui/utils/Blur.cpp +12 −0 Original line number Original line Diff line number Diff line Loading @@ -19,6 +19,7 @@ #include <math.h> #include <math.h> #include "Blur.h" #include "Blur.h" #include "MathUtils.h" namespace android { namespace android { namespace uirenderer { namespace uirenderer { Loading @@ -35,6 +36,17 @@ float Blur::convertSigmaToRadius(float sigma) { return sigma > 0.5f ? (sigma - 0.5f) / BLUR_SIGMA_SCALE : 0.0f; return sigma > 0.5f ? (sigma - 0.5f) / BLUR_SIGMA_SCALE : 0.0f; } } // if the original radius was on an integer boundary and the resulting radius // is within the conversion error tolerance then we attempt to snap to the // original integer boundary. uint32_t Blur::convertRadiusToInt(float radius) { const float radiusCeil = ceilf(radius); if (MathUtils::areEqual(radiusCeil, radius)) { return radiusCeil; } return radius; } /** /** * HWUI has used a slightly different equation than Skia to generate the value * HWUI has used a slightly different equation than Skia to generate the value * for sigma and to preserve compatibility we have kept that logic. * for sigma and to preserve compatibility we have kept that logic. Loading libs/hwui/utils/Blur.h +5 −1 Original line number Original line Diff line number Diff line Loading @@ -27,8 +27,12 @@ class Blur { public: public: // If radius > 0, return the corresponding sigma, else return 0 // If radius > 0, return the corresponding sigma, else return 0 ANDROID_API static float convertRadiusToSigma(float radius); ANDROID_API static float convertRadiusToSigma(float radius); // If sigma > 0.6, return the corresponding radius, else return 0 // If sigma > 0.5, return the corresponding radius, else return 0 ANDROID_API static float convertSigmaToRadius(float sigma); ANDROID_API static float convertSigmaToRadius(float sigma); // If the original radius was on an integer boundary then after the sigma to // radius conversion a small rounding error may be introduced. This function // accounts for that error and snaps to the appropriate integer boundary. static uint32_t convertRadiusToInt(float radius); static void generateGaussianWeights(float* weights, int32_t radius); static void generateGaussianWeights(float* weights, int32_t radius); static void horizontal(float* weights, int32_t radius, const uint8_t* source, static void horizontal(float* weights, int32_t radius, const uint8_t* source, Loading Loading
libs/hwui/FontRenderer.cpp +13 −11 Original line number Original line Diff line number Diff line Loading @@ -592,7 +592,7 @@ void FontRenderer::setFont(const SkPaint* paint, const mat4& matrix) { } } FontRenderer::DropShadow FontRenderer::renderDropShadow(const SkPaint* paint, const char *text, FontRenderer::DropShadow FontRenderer::renderDropShadow(const SkPaint* paint, const char *text, uint32_t startIndex, uint32_t len, int numGlyphs, uint32_t radius, const float* positions) { uint32_t startIndex, uint32_t len, int numGlyphs, float radius, const float* positions) { checkInit(); checkInit(); DropShadow image; DropShadow image; Loading @@ -613,8 +613,9 @@ FontRenderer::DropShadow FontRenderer::renderDropShadow(const SkPaint* paint, co Rect bounds; Rect bounds; mCurrentFont->measure(paint, text, startIndex, len, numGlyphs, &bounds, positions); mCurrentFont->measure(paint, text, startIndex, len, numGlyphs, &bounds, positions); uint32_t paddedWidth = (uint32_t) (bounds.right - bounds.left) + 2 * radius; uint32_t intRadius = Blur::convertRadiusToInt(radius); uint32_t paddedHeight = (uint32_t) (bounds.top - bounds.bottom) + 2 * radius; uint32_t paddedWidth = (uint32_t) (bounds.right - bounds.left) + 2 * intRadius; uint32_t paddedHeight = (uint32_t) (bounds.top - bounds.bottom) + 2 * intRadius; uint32_t maxSize = Caches::getInstance().maxTextureSize; uint32_t maxSize = Caches::getInstance().maxTextureSize; if (paddedWidth > maxSize || paddedHeight > maxSize) { if (paddedWidth > maxSize || paddedHeight > maxSize) { Loading @@ -635,8 +636,8 @@ FontRenderer::DropShadow FontRenderer::renderDropShadow(const SkPaint* paint, co memset(dataBuffer, 0, size); memset(dataBuffer, 0, size); int penX = radius - bounds.left; int penX = intRadius - bounds.left; int penY = radius - bounds.bottom; int penY = intRadius - bounds.bottom; if ((bounds.right > bounds.left) && (bounds.top > bounds.bottom)) { if ((bounds.right > bounds.left) && (bounds.top > bounds.bottom)) { // text has non-whitespace, so draw and blur to create the shadow // text has non-whitespace, so draw and blur to create the shadow Loading Loading @@ -727,9 +728,10 @@ void FontRenderer::removeFont(const Font* font) { } } } } void FontRenderer::blurImage(uint8_t** image, int32_t width, int32_t height, int32_t radius) { void FontRenderer::blurImage(uint8_t** image, int32_t width, int32_t height, float radius) { uint32_t intRadius = Blur::convertRadiusToInt(radius); #ifdef ANDROID_ENABLE_RENDERSCRIPT #ifdef ANDROID_ENABLE_RENDERSCRIPT if (width * height * radius >= RS_MIN_INPUT_CUTOFF) { if (width * height * intRadius >= RS_MIN_INPUT_CUTOFF) { uint8_t* outImage = (uint8_t*) memalign(RS_CPU_ALLOCATION_ALIGNMENT, width * height); uint8_t* outImage = (uint8_t*) memalign(RS_CPU_ALLOCATION_ALIGNMENT, width * height); if (mRs == 0) { if (mRs == 0) { Loading Loading @@ -768,12 +770,12 @@ void FontRenderer::blurImage(uint8_t** image, int32_t width, int32_t height, int } } #endif #endif float *gaussian = new float[2 * radius + 1]; float *gaussian = new float[2 * intRadius + 1]; Blur::generateGaussianWeights(gaussian, radius); Blur::generateGaussianWeights(gaussian, intRadius); uint8_t* scratch = new uint8_t[width * height]; uint8_t* scratch = new uint8_t[width * height]; Blur::horizontal(gaussian, radius, *image, scratch, width, height); Blur::horizontal(gaussian, intRadius, *image, scratch, width, height); Blur::vertical(gaussian, radius, scratch, *image, width, height); Blur::vertical(gaussian, intRadius, scratch, *image, width, height); delete[] gaussian; delete[] gaussian; delete[] scratch; delete[] scratch; Loading
libs/hwui/FontRenderer.h +2 −2 Original line number Original line Diff line number Diff line Loading @@ -129,7 +129,7 @@ public: // After renderDropShadow returns, the called owns the memory in DropShadow.image // After renderDropShadow returns, the called owns the memory in DropShadow.image // and is responsible for releasing it when it's done with it // and is responsible for releasing it when it's done with it DropShadow renderDropShadow(const SkPaint* paint, const char *text, uint32_t startIndex, DropShadow renderDropShadow(const SkPaint* paint, const char *text, uint32_t startIndex, uint32_t len, int numGlyphs, uint32_t radius, const float* positions); uint32_t len, int numGlyphs, float radius, const float* positions); void setTextureFiltering(bool linearFiltering) { void setTextureFiltering(bool linearFiltering) { mLinearFiltering = linearFiltering; mLinearFiltering = linearFiltering; Loading Loading @@ -218,7 +218,7 @@ private: int32_t width, int32_t height); int32_t width, int32_t height); // the input image handle may have its pointer replaced (to avoid copies) // the input image handle may have its pointer replaced (to avoid copies) void blurImage(uint8_t** image, int32_t width, int32_t height, int32_t radius); void blurImage(uint8_t** image, int32_t width, int32_t height, float radius); }; }; }; // namespace uirenderer }; // namespace uirenderer Loading
libs/hwui/utils/Blur.cpp +12 −0 Original line number Original line Diff line number Diff line Loading @@ -19,6 +19,7 @@ #include <math.h> #include <math.h> #include "Blur.h" #include "Blur.h" #include "MathUtils.h" namespace android { namespace android { namespace uirenderer { namespace uirenderer { Loading @@ -35,6 +36,17 @@ float Blur::convertSigmaToRadius(float sigma) { return sigma > 0.5f ? (sigma - 0.5f) / BLUR_SIGMA_SCALE : 0.0f; return sigma > 0.5f ? (sigma - 0.5f) / BLUR_SIGMA_SCALE : 0.0f; } } // if the original radius was on an integer boundary and the resulting radius // is within the conversion error tolerance then we attempt to snap to the // original integer boundary. uint32_t Blur::convertRadiusToInt(float radius) { const float radiusCeil = ceilf(radius); if (MathUtils::areEqual(radiusCeil, radius)) { return radiusCeil; } return radius; } /** /** * HWUI has used a slightly different equation than Skia to generate the value * HWUI has used a slightly different equation than Skia to generate the value * for sigma and to preserve compatibility we have kept that logic. * for sigma and to preserve compatibility we have kept that logic. Loading
libs/hwui/utils/Blur.h +5 −1 Original line number Original line Diff line number Diff line Loading @@ -27,8 +27,12 @@ class Blur { public: public: // If radius > 0, return the corresponding sigma, else return 0 // If radius > 0, return the corresponding sigma, else return 0 ANDROID_API static float convertRadiusToSigma(float radius); ANDROID_API static float convertRadiusToSigma(float radius); // If sigma > 0.6, return the corresponding radius, else return 0 // If sigma > 0.5, return the corresponding radius, else return 0 ANDROID_API static float convertSigmaToRadius(float sigma); ANDROID_API static float convertSigmaToRadius(float sigma); // If the original radius was on an integer boundary then after the sigma to // radius conversion a small rounding error may be introduced. This function // accounts for that error and snaps to the appropriate integer boundary. static uint32_t convertRadiusToInt(float radius); static void generateGaussianWeights(float* weights, int32_t radius); static void generateGaussianWeights(float* weights, int32_t radius); static void horizontal(float* weights, int32_t radius, const uint8_t* source, static void horizontal(float* weights, int32_t radius, const uint8_t* source, Loading