diff options
Diffstat (limited to 'libs/hwui/utils')
-rw-r--r-- | libs/hwui/utils/Blur.cpp | 45 | ||||
-rw-r--r-- | libs/hwui/utils/Blur.h | 10 | ||||
-rw-r--r-- | libs/hwui/utils/GLUtils.cpp | 52 | ||||
-rw-r--r-- | libs/hwui/utils/GLUtils.h | 35 | ||||
-rw-r--r-- | libs/hwui/utils/Macros.h | 32 | ||||
-rw-r--r-- | libs/hwui/utils/MathUtils.h | 85 |
6 files changed, 252 insertions, 7 deletions
diff --git a/libs/hwui/utils/Blur.cpp b/libs/hwui/utils/Blur.cpp index 85d90d0..877a422 100644 --- a/libs/hwui/utils/Blur.cpp +++ b/libs/hwui/utils/Blur.cpp @@ -19,10 +19,47 @@ #include <math.h> #include "Blur.h" +#include "MathUtils.h" namespace android { namespace uirenderer { +// This constant approximates the scaling done in the software path's +// "high quality" mode, in SkBlurMask::Blur() (1 / sqrt(3)). +static const float BLUR_SIGMA_SCALE = 0.57735f; + +float Blur::convertRadiusToSigma(float radius) { + return radius > 0 ? BLUR_SIGMA_SCALE * radius + 0.5f : 0.0f; +} + +float Blur::convertSigmaToRadius(float sigma) { + 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 + * for sigma and to preserve compatibility we have kept that logic. + * + * Based on some experimental radius and sigma values we approximate the + * equation sigma = f(radius) as sigma = radius * 0.3 + 0.6. The larger the + * radius gets, the more our gaussian blur will resemble a box blur since with + * large sigma the gaussian curve begins to lose its shape. + */ +static float legacyConvertRadiusToSigma(float radius) { + return radius > 0 ? 0.3f * radius + 0.6f : 0.0f; +} + void Blur::generateGaussianWeights(float* weights, int32_t radius) { // Compute gaussian weights for the blur // e is the euler's number @@ -31,13 +68,7 @@ void Blur::generateGaussianWeights(float* weights, int32_t radius) { // g(x) = ( 1 / sqrt( 2 * pi ) * sigma) * e ^ ( -x^2 / 2 * sigma^2 ) // x is of the form [-radius .. 0 .. radius] // and sigma varies with radius. - // Based on some experimental radius values and sigma's - // we approximately fit sigma = f(radius) as - // sigma = radius * 0.3 + 0.6 - // The larger the radius gets, the more our gaussian blur - // will resemble a box blur since with large sigma - // the gaussian curve begins to lose its shape - float sigma = 0.3f * (float) radius + 0.6f; + float sigma = legacyConvertRadiusToSigma((float) radius); // Now compute the coefficints // We will store some redundant values to save some math during diff --git a/libs/hwui/utils/Blur.h b/libs/hwui/utils/Blur.h index 6c176e9..b145333 100644 --- a/libs/hwui/utils/Blur.h +++ b/libs/hwui/utils/Blur.h @@ -18,12 +18,22 @@ #define ANDROID_HWUI_BLUR_H #include <stdint.h> +#include <cutils/compiler.h> namespace android { namespace uirenderer { class Blur { public: + // If radius > 0, return the corresponding sigma, else return 0 + ANDROID_API static float convertRadiusToSigma(float radius); + // If sigma > 0.5, return the corresponding radius, else return 0 + 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 horizontal(float* weights, int32_t radius, const uint8_t* source, uint8_t* dest, int32_t width, int32_t height); diff --git a/libs/hwui/utils/GLUtils.cpp b/libs/hwui/utils/GLUtils.cpp new file mode 100644 index 0000000..9b298ca --- /dev/null +++ b/libs/hwui/utils/GLUtils.cpp @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * 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. + */ + +#define LOG_TAG "OpenGLRenderer" + +#include <GLES2/gl2.h> +#include <GLES2/gl2ext.h> + +#include <utils/Log.h> + +#include "GLUtils.h" + +namespace android { +namespace uirenderer { + +void GLUtils::dumpGLErrors() { + GLenum status = GL_NO_ERROR; + while ((status = glGetError()) != GL_NO_ERROR) { + switch (status) { + case GL_INVALID_ENUM: + ALOGE("GL error: GL_INVALID_ENUM"); + break; + case GL_INVALID_VALUE: + ALOGE("GL error: GL_INVALID_VALUE"); + break; + case GL_INVALID_OPERATION: + ALOGE("GL error: GL_INVALID_OPERATION"); + break; + case GL_OUT_OF_MEMORY: + ALOGE("GL error: Out of memory!"); + break; + default: + ALOGE("GL error: 0x%x", status); + } + } +} + +}; // namespace uirenderer +}; // namespace android diff --git a/libs/hwui/utils/GLUtils.h b/libs/hwui/utils/GLUtils.h new file mode 100644 index 0000000..890e374 --- /dev/null +++ b/libs/hwui/utils/GLUtils.h @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * 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. + */ +#ifndef GLUTILS_H +#define GLUTILS_H + +namespace android { +namespace uirenderer { + +class GLUtils { +private: +public: + /** + * Print out any GL errors with ALOGE + */ + static void dumpGLErrors(); + +}; // class GLUtils + +} /* namespace uirenderer */ +} /* namespace android */ + +#endif /* GLUTILS_H */ diff --git a/libs/hwui/utils/Macros.h b/libs/hwui/utils/Macros.h new file mode 100644 index 0000000..5b7c87c --- /dev/null +++ b/libs/hwui/utils/Macros.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * 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. + */ +#ifndef MACROS_H +#define MACROS_H + +#define PREVENT_COPY_AND_ASSIGN(Type) \ + private: \ + Type(const Type&); \ + void operator=(const Type&) + +#define DESCRIPTION_TYPE(Type) \ + int compare(const Type& rhs) const { return memcmp(this, &rhs, sizeof(Type));} \ + bool operator==(const Type& other) const { return compare(other) == 0; } \ + bool operator!=(const Type& other) const { return compare(other) != 0; } \ + friend inline int strictly_order_type(const Type& lhs, const Type& rhs) { return lhs.compare(rhs) < 0; } \ + friend inline int compare_type(const Type& lhs, const Type& rhs) { return lhs.compare(rhs); } \ + friend inline hash_t hash_type(const Type& entry) { return entry.hash(); } + +#endif /* MACROS_H */ diff --git a/libs/hwui/utils/MathUtils.h b/libs/hwui/utils/MathUtils.h new file mode 100644 index 0000000..6fb0411 --- /dev/null +++ b/libs/hwui/utils/MathUtils.h @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * 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. + */ +#ifndef MATHUTILS_H +#define MATHUTILS_H + +namespace android { +namespace uirenderer { + +#define NON_ZERO_EPSILON (0.001f) +#define ALPHA_EPSILON (0.001f) + +class MathUtils { +public: + /** + * Check for floats that are close enough to zero. + */ + inline static bool isZero(float value) { + return (value >= -NON_ZERO_EPSILON) && (value <= NON_ZERO_EPSILON); + } + + inline static bool isPositive(float value) { + return value >= NON_ZERO_EPSILON; + } + + /** + * Clamps alpha value, and snaps when very near 0 or 1 + */ + inline static float clampAlpha(float alpha) { + if (alpha <= ALPHA_EPSILON) { + return 0; + } else if (alpha >= (1 - ALPHA_EPSILON)) { + return 1; + } else { + return alpha; + } + } + + /* + * Clamps positive tessellation scale values + */ + inline static float clampTessellationScale(float scale) { + const float MIN_SCALE = 0.0001; + const float MAX_SCALE = 1e10; + if (scale < MIN_SCALE) { + return MIN_SCALE; + } else if (scale > MAX_SCALE) { + return MAX_SCALE; + } + return scale; + } + + inline static bool areEqual(float valueA, float valueB) { + return isZero(valueA - valueB); + } + + inline static int max(int a, int b) { + return a > b ? a : b; + } + + inline static int min(int a, int b) { + return a < b ? a : b; + } + + inline static float lerp(float v1, float v2, float t) { + return v1 + ((v2 - v1) * t); + } +}; // class MathUtils + +} /* namespace uirenderer */ +} /* namespace android */ + +#endif /* MATHUTILS_H */ |