Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e4143716 authored by Sergei Vasilinetc's avatar Sergei Vasilinetc Committed by Android (Google) Code Review
Browse files

Merge "Stop comparing Descriptions with memcmp" into nyc-dev

parents e60b8f89 7224e2b6
Loading
Loading
Loading
Loading
+56 −13
Original line number Original line Diff line number Diff line
@@ -19,6 +19,7 @@
#include <SkColor.h>
#include <SkColor.h>
#include <SkPaint.h>
#include <SkPaint.h>
#include <SkPath.h>
#include <SkPath.h>
#include <SkPathEffect.h>
#include <SkRect.h>
#include <SkRect.h>


#include <utils/JenkinsHash.h>
#include <utils/JenkinsHash.h>
@@ -35,18 +36,34 @@
namespace android {
namespace android {
namespace uirenderer {
namespace uirenderer {


template <class T>
static bool compareWidthHeight(const T& lhs, const T& rhs) {
    return (lhs.mWidth == rhs.mWidth) && (lhs.mHeight == rhs.mHeight);
}

static bool compareRoundRects(const PathDescription::Shape::RoundRect& lhs,
        const PathDescription::Shape::RoundRect& rhs) {
    return compareWidthHeight(lhs, rhs) && lhs.mRx == rhs.mRx && lhs.mRy == rhs.mRy;
}

static bool compareArcs(const PathDescription::Shape::Arc& lhs, const PathDescription::Shape::Arc& rhs) {
    return compareWidthHeight(lhs, rhs) && lhs.mStartAngle == rhs.mStartAngle &&
            lhs.mSweepAngle == rhs.mSweepAngle && lhs.mUseCenter == rhs.mUseCenter;
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// Cache entries
// Cache entries
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////


PathDescription::PathDescription()
PathDescription::PathDescription()
        : type(kShapeNone)
        : type(ShapeType::None)
        , join(SkPaint::kDefault_Join)
        , join(SkPaint::kDefault_Join)
        , cap(SkPaint::kDefault_Cap)
        , cap(SkPaint::kDefault_Cap)
        , style(SkPaint::kFill_Style)
        , style(SkPaint::kFill_Style)
        , miter(4.0f)
        , miter(4.0f)
        , strokeWidth(1.0f)
        , strokeWidth(1.0f)
        , pathEffect(nullptr) {
        , pathEffect(nullptr) {
    // Shape bits should be set to zeroes, because they are used for hash calculation.
    memset(&shape, 0, sizeof(Shape));
    memset(&shape, 0, sizeof(Shape));
}
}


@@ -58,11 +75,12 @@ PathDescription::PathDescription(ShapeType type, const SkPaint* paint)
        , miter(paint->getStrokeMiter())
        , miter(paint->getStrokeMiter())
        , strokeWidth(paint->getStrokeWidth())
        , strokeWidth(paint->getStrokeWidth())
        , pathEffect(paint->getPathEffect()) {
        , pathEffect(paint->getPathEffect()) {
    // Shape bits should be set to zeroes, because they are used for hash calculation.
    memset(&shape, 0, sizeof(Shape));
    memset(&shape, 0, sizeof(Shape));
}
}


hash_t PathDescription::hash() const {
hash_t PathDescription::hash() const {
    uint32_t hash = JenkinsHashMix(0, type);
    uint32_t hash = JenkinsHashMix(0, static_cast<int>(type));
    hash = JenkinsHashMix(hash, join);
    hash = JenkinsHashMix(hash, join);
    hash = JenkinsHashMix(hash, cap);
    hash = JenkinsHashMix(hash, cap);
    hash = JenkinsHashMix(hash, style);
    hash = JenkinsHashMix(hash, style);
@@ -73,6 +91,32 @@ hash_t PathDescription::hash() const {
    return JenkinsHashWhiten(hash);
    return JenkinsHashWhiten(hash);
}
}


bool PathDescription::operator==(const PathDescription& rhs) const {
    if (type != rhs.type) return false;
    if (join != rhs.join) return false;
    if (cap != rhs.cap) return false;
    if (style != rhs.style) return false;
    if (miter != rhs.miter) return false;
    if (strokeWidth != rhs.strokeWidth) return false;
    if (pathEffect != rhs.pathEffect) return false;
    switch (type) {
        case ShapeType::None:
            return 0;
        case ShapeType::Rect:
            return compareWidthHeight(shape.rect, rhs.shape.rect);
        case ShapeType::RoundRect:
            return compareRoundRects(shape.roundRect, rhs.shape.roundRect);
        case ShapeType::Circle:
            return shape.circle.mRadius == rhs.shape.circle.mRadius;
        case ShapeType::Oval:
            return compareWidthHeight(shape.oval, rhs.shape.oval);
        case ShapeType::Arc:
            return compareArcs(shape.arc, rhs.shape.arc);
        case ShapeType::Path:
            return shape.path.mGenerationID == rhs.shape.path.mGenerationID;
    }
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// Utilities
// Utilities
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
@@ -322,7 +366,7 @@ void PathCache::clearGarbage() {
            LruCache<PathDescription, PathTexture*>::Iterator iter(mCache);
            LruCache<PathDescription, PathTexture*>::Iterator iter(mCache);
            while (iter.next()) {
            while (iter.next()) {
                const PathDescription& key = iter.key();
                const PathDescription& key = iter.key();
                if (key.type == kShapePath && key.shape.path.mGenerationID == generationID) {
                if (key.type == ShapeType::Path && key.shape.path.mGenerationID == generationID) {
                    pathsToRemove.push(key);
                    pathsToRemove.push(key);
                }
                }
            }
            }
@@ -336,7 +380,7 @@ void PathCache::clearGarbage() {
}
}


PathTexture* PathCache::get(const SkPath* path, const SkPaint* paint) {
PathTexture* PathCache::get(const SkPath* path, const SkPaint* paint) {
    PathDescription entry(kShapePath, paint);
    PathDescription entry(ShapeType::Path, paint);
    entry.shape.path.mGenerationID = path->getGenerationID();
    entry.shape.path.mGenerationID = path->getGenerationID();


    PathTexture* texture = mCache.get(entry);
    PathTexture* texture = mCache.get(entry);
@@ -366,9 +410,8 @@ PathTexture* PathCache::get(const SkPath* path, const SkPaint* paint) {
    return texture;
    return texture;
}
}


void PathCache::remove(const SkPath* path, const SkPaint* paint)
void PathCache::remove(const SkPath* path, const SkPaint* paint) {
{
    PathDescription entry(ShapeType::Path, paint);
    PathDescription entry(kShapePath, paint);
    entry.shape.path.mGenerationID = path->getGenerationID();
    entry.shape.path.mGenerationID = path->getGenerationID();
    mCache.remove(entry);
    mCache.remove(entry);
}
}
@@ -378,7 +421,7 @@ void PathCache::precache(const SkPath* path, const SkPaint* paint) {
        return;
        return;
    }
    }


    PathDescription entry(kShapePath, paint);
    PathDescription entry(ShapeType::Path, paint);
    entry.shape.path.mGenerationID = path->getGenerationID();
    entry.shape.path.mGenerationID = path->getGenerationID();


    PathTexture* texture = mCache.get(entry);
    PathTexture* texture = mCache.get(entry);
@@ -417,7 +460,7 @@ void PathCache::precache(const SkPath* path, const SkPaint* paint) {


PathTexture* PathCache::getRoundRect(float width, float height,
PathTexture* PathCache::getRoundRect(float width, float height,
        float rx, float ry, const SkPaint* paint) {
        float rx, float ry, const SkPaint* paint) {
    PathDescription entry(kShapeRoundRect, paint);
    PathDescription entry(ShapeType::RoundRect, paint);
    entry.shape.roundRect.mWidth = width;
    entry.shape.roundRect.mWidth = width;
    entry.shape.roundRect.mHeight = height;
    entry.shape.roundRect.mHeight = height;
    entry.shape.roundRect.mRx = rx;
    entry.shape.roundRect.mRx = rx;
@@ -442,7 +485,7 @@ PathTexture* PathCache::getRoundRect(float width, float height,
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////


PathTexture* PathCache::getCircle(float radius, const SkPaint* paint) {
PathTexture* PathCache::getCircle(float radius, const SkPaint* paint) {
    PathDescription entry(kShapeCircle, paint);
    PathDescription entry(ShapeType::Circle, paint);
    entry.shape.circle.mRadius = radius;
    entry.shape.circle.mRadius = radius;


    PathTexture* texture = get(entry);
    PathTexture* texture = get(entry);
@@ -462,7 +505,7 @@ PathTexture* PathCache::getCircle(float radius, const SkPaint* paint) {
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////


PathTexture* PathCache::getOval(float width, float height, const SkPaint* paint) {
PathTexture* PathCache::getOval(float width, float height, const SkPaint* paint) {
    PathDescription entry(kShapeOval, paint);
    PathDescription entry(ShapeType::Oval, paint);
    entry.shape.oval.mWidth = width;
    entry.shape.oval.mWidth = width;
    entry.shape.oval.mHeight = height;
    entry.shape.oval.mHeight = height;


@@ -485,7 +528,7 @@ PathTexture* PathCache::getOval(float width, float height, const SkPaint* paint)
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////


PathTexture* PathCache::getRect(float width, float height, const SkPaint* paint) {
PathTexture* PathCache::getRect(float width, float height, const SkPaint* paint) {
    PathDescription entry(kShapeRect, paint);
    PathDescription entry(ShapeType::Rect, paint);
    entry.shape.rect.mWidth = width;
    entry.shape.rect.mWidth = width;
    entry.shape.rect.mHeight = height;
    entry.shape.rect.mHeight = height;


@@ -509,7 +552,7 @@ PathTexture* PathCache::getRect(float width, float height, const SkPaint* paint)


PathTexture* PathCache::getArc(float width, float height,
PathTexture* PathCache::getArc(float width, float height,
        float startAngle, float sweepAngle, bool useCenter, const SkPaint* paint) {
        float startAngle, float sweepAngle, bool useCenter, const SkPaint* paint) {
    PathDescription entry(kShapeArc, paint);
    PathDescription entry(ShapeType::Arc, paint);
    entry.shape.arc.mWidth = width;
    entry.shape.arc.mWidth = width;
    entry.shape.arc.mHeight = height;
    entry.shape.arc.mHeight = height;
    entry.shape.arc.mStartAngle = startAngle;
    entry.shape.arc.mStartAngle = startAngle;
+10 −11
Original line number Original line Diff line number Diff line
@@ -25,6 +25,7 @@
#include "utils/Pair.h"
#include "utils/Pair.h"


#include <GLES2/gl2.h>
#include <GLES2/gl2.h>
#include <SkPaint.h>
#include <SkPath.h>
#include <SkPath.h>
#include <utils/LruCache.h>
#include <utils/LruCache.h>
#include <utils/Mutex.h>
#include <utils/Mutex.h>
@@ -108,18 +109,18 @@ private:
    sp<Task<SkBitmap*> > mTask;
    sp<Task<SkBitmap*> > mTask;
}; // struct PathTexture
}; // struct PathTexture


enum ShapeType {
enum class ShapeType {
    kShapeNone,
    None,
    kShapeRect,
    Rect,
    kShapeRoundRect,
    RoundRect,
    kShapeCircle,
    Circle,
    kShapeOval,
    Oval,
    kShapeArc,
    Arc,
    kShapePath
    Path
};
};


struct PathDescription {
struct PathDescription {
    DESCRIPTION_TYPE(PathDescription);
    HASHABLE_TYPE(PathDescription);
    ShapeType type;
    ShapeType type;
    SkPaint::Join join;
    SkPaint::Join join;
    SkPaint::Cap cap;
    SkPaint::Cap cap;
@@ -159,8 +160,6 @@ struct PathDescription {


    PathDescription();
    PathDescription();
    PathDescription(ShapeType shapeType, const SkPaint* paint);
    PathDescription(ShapeType shapeType, const SkPaint* paint);

    hash_t hash() const;
};
};


/**
/**
+33 −7
Original line number Original line Diff line number Diff line
@@ -35,13 +35,14 @@ namespace uirenderer {
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////


TessellationCache::Description::Description()
TessellationCache::Description::Description()
        : type(kNone)
        : type(Type::None)
        , scaleX(1.0f)
        , scaleX(1.0f)
        , scaleY(1.0f)
        , scaleY(1.0f)
        , aa(false)
        , aa(false)
        , cap(SkPaint::kDefault_Cap)
        , cap(SkPaint::kDefault_Cap)
        , style(SkPaint::kFill_Style)
        , style(SkPaint::kFill_Style)
        , strokeWidth(1.0f) {
        , strokeWidth(1.0f) {
    // Shape bits should be set to zeroes, because they are used for hash calculation.
    memset(&shape, 0, sizeof(Shape));
    memset(&shape, 0, sizeof(Shape));
}
}


@@ -52,11 +53,30 @@ TessellationCache::Description::Description(Type type, const Matrix4& transform,
        , style(paint.getStyle())
        , style(paint.getStyle())
        , strokeWidth(paint.getStrokeWidth()) {
        , strokeWidth(paint.getStrokeWidth()) {
    PathTessellator::extractTessellationScales(transform, &scaleX, &scaleY);
    PathTessellator::extractTessellationScales(transform, &scaleX, &scaleY);
    // Shape bits should be set to zeroes, because they are used for hash calculation.
    memset(&shape, 0, sizeof(Shape));
    memset(&shape, 0, sizeof(Shape));
}
}


bool TessellationCache::Description::operator==(const TessellationCache::Description& rhs) const {
    if (type != rhs.type) return false;
    if (scaleX != rhs.scaleX) return false;
    if (scaleY != rhs.scaleY) return false;
    if (aa != rhs.aa) return false;
    if (cap != rhs.cap) return false;
    if (style != rhs.style) return false;
    if (strokeWidth != rhs.strokeWidth) return false;
    if (type == Type::None) return true;
    const Shape::RoundRect& lRect = shape.roundRect;
    const Shape::RoundRect& rRect = rhs.shape.roundRect;

    if (lRect.width != rRect.width) return false;
    if (lRect.height != rRect.height) return false;
    if (lRect.rx != rRect.rx) return false;
    return lRect.ry == rRect.ry;
}

hash_t TessellationCache::Description::hash() const {
hash_t TessellationCache::Description::hash() const {
    uint32_t hash = JenkinsHashMix(0, type);
    uint32_t hash = JenkinsHashMix(0, static_cast<int>(type));
    hash = JenkinsHashMix(hash, aa);
    hash = JenkinsHashMix(hash, aa);
    hash = JenkinsHashMix(hash, cap);
    hash = JenkinsHashMix(hash, cap);
    hash = JenkinsHashMix(hash, style);
    hash = JenkinsHashMix(hash, style);
@@ -77,17 +97,23 @@ void TessellationCache::Description::setupMatrixAndPaint(Matrix4* matrix, SkPain


TessellationCache::ShadowDescription::ShadowDescription()
TessellationCache::ShadowDescription::ShadowDescription()
        : nodeKey(nullptr) {
        : nodeKey(nullptr) {
    memset(&matrixData, 0, 16 * sizeof(float));
    memset(&matrixData, 0, sizeof(matrixData));
}
}


TessellationCache::ShadowDescription::ShadowDescription(const void* nodeKey, const Matrix4* drawTransform)
TessellationCache::ShadowDescription::ShadowDescription(const SkPath* nodeKey, const Matrix4* drawTransform)
        : nodeKey(nodeKey) {
        : nodeKey(nodeKey) {
    memcpy(&matrixData, drawTransform->data, 16 * sizeof(float));
    memcpy(&matrixData, drawTransform->data, sizeof(matrixData));
}

bool TessellationCache::ShadowDescription::operator==(
        const TessellationCache::ShadowDescription& rhs) const {
    return nodeKey == rhs.nodeKey
            && memcmp(&matrixData, &rhs.matrixData, sizeof(matrixData)) == 0;
}
}


hash_t TessellationCache::ShadowDescription::hash() const {
hash_t TessellationCache::ShadowDescription::hash() const {
    uint32_t hash = JenkinsHashMixBytes(0, (uint8_t*) &nodeKey, sizeof(const void*));
    uint32_t hash = JenkinsHashMixBytes(0, (uint8_t*) &nodeKey, sizeof(const void*));
    hash = JenkinsHashMixBytes(hash, (uint8_t*) &matrixData, 16 * sizeof(float));
    hash = JenkinsHashMixBytes(hash, (uint8_t*) &matrixData, sizeof(matrixData));
    return JenkinsHashWhiten(hash);
    return JenkinsHashWhiten(hash);
}
}


@@ -428,7 +454,7 @@ static VertexBuffer* tessellateRoundRect(const TessellationCache::Description& d
TessellationCache::Buffer* TessellationCache::getRoundRectBuffer(
TessellationCache::Buffer* TessellationCache::getRoundRectBuffer(
        const Matrix4& transform, const SkPaint& paint,
        const Matrix4& transform, const SkPaint& paint,
        float width, float height, float rx, float ry) {
        float width, float height, float rx, float ry) {
    Description entry(Description::kRoundRect, transform, paint);
    Description entry(Description::Type::RoundRect, transform, paint);
    entry.shape.roundRect.width = width;
    entry.shape.roundRect.width = width;
    entry.shape.roundRect.height = height;
    entry.shape.roundRect.height = height;
    entry.shape.roundRect.rx = rx;
    entry.shape.roundRect.rx = rx;
+7 −9
Original line number Original line Diff line number Diff line
@@ -52,10 +52,10 @@ public:
    typedef Pair<VertexBuffer*, VertexBuffer*> vertexBuffer_pair_t;
    typedef Pair<VertexBuffer*, VertexBuffer*> vertexBuffer_pair_t;


    struct Description {
    struct Description {
        DESCRIPTION_TYPE(Description);
        HASHABLE_TYPE(Description);
        enum Type {
        enum class Type {
            kNone,
            None,
            kRoundRect,
            RoundRect,
        };
        };


        Type type;
        Type type;
@@ -76,18 +76,16 @@ public:


        Description();
        Description();
        Description(Type type, const Matrix4& transform, const SkPaint& paint);
        Description(Type type, const Matrix4& transform, const SkPaint& paint);
        hash_t hash() const;
        void setupMatrixAndPaint(Matrix4* matrix, SkPaint* paint) const;
        void setupMatrixAndPaint(Matrix4* matrix, SkPaint* paint) const;
    };
    };


    struct ShadowDescription {
    struct ShadowDescription {
        DESCRIPTION_TYPE(ShadowDescription);
        HASHABLE_TYPE(ShadowDescription);
        const void* nodeKey;
        const SkPath* nodeKey;
        float matrixData[16];
        float matrixData[16];


        ShadowDescription();
        ShadowDescription();
        ShadowDescription(const void* nodeKey, const Matrix4* drawTransform);
        ShadowDescription(const SkPath* nodeKey, const Matrix4* drawTransform);
        hash_t hash() const;
    };
    };


    class ShadowTask : public Task<vertexBuffer_pair_t> {
    class ShadowTask : public Task<vertexBuffer_pair_t> {
+4 −6
Original line number Original line Diff line number Diff line
@@ -23,12 +23,10 @@
        Type(const Type&) = delete; \
        Type(const Type&) = delete; \
        void operator=(const Type&) = delete
        void operator=(const Type&) = delete


#define DESCRIPTION_TYPE(Type) \
#define HASHABLE_TYPE(Type) \
        int compare(const Type& rhs) const { return memcmp(this, &rhs, sizeof(Type));} \
        bool operator==(const Type& other) const; \
        bool operator==(const Type& other) const { return compare(other) == 0; } \
        hash_t hash() const; \
        bool operator!=(const Type& other) const { return compare(other) != 0; } \
        bool operator!=(const Type& other) const { return !(*this == other); } \
        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(); }
        friend inline hash_t hash_type(const Type& entry) { return entry.hash(); }


#define REQUIRE_COMPATIBLE_LAYOUT(Type) \
#define REQUIRE_COMPATIBLE_LAYOUT(Type) \