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

Commit 6e49c9f0 authored by Mike Reed's avatar Mike Reed
Browse files

switch over clip calls to use SkClipOp instead of SkRegion::Op

Change-Id: I67d23c487b5249bc31d96e3b2393f693c0b2bcff
parent 7bdd131a
Loading
Loading
Loading
Loading
+26 −6
Original line number Diff line number Diff line
@@ -183,26 +183,46 @@ static jboolean quickRejectPath(JNIEnv* env, jobject, jlong canvasHandle, jlong
    return result ? JNI_TRUE : JNI_FALSE;
}

// SkRegion::Op and SkClipOp are numerically identical, so we can freely cast
// from one to the other (though SkClipOp is destined to become a strict subset)
static_assert(SkRegion::kDifference_Op == static_cast<SkRegion::Op>(kDifference_SkClipOp), "");
static_assert(SkRegion::kIntersect_Op == static_cast<SkRegion::Op>(kIntersect_SkClipOp), "");
static_assert(SkRegion::kUnion_Op == static_cast<SkRegion::Op>(kUnion_SkClipOp), "");
static_assert(SkRegion::kXOR_Op == static_cast<SkRegion::Op>(kXOR_SkClipOp), "");
static_assert(SkRegion::kReverseDifference_Op == static_cast<SkRegion::Op>(kReverseDifference_SkClipOp), "");
static_assert(SkRegion::kReplace_Op == static_cast<SkRegion::Op>(kReplace_SkClipOp), "");

static SkClipOp opHandleToClipOp(jint opHandle) {
    // The opHandle is defined in Canvas.java to be Region::Op
    SkRegion::Op rgnOp = static_cast<SkRegion::Op>(opHandle);

    // In the future, when we no longer support the wide range of ops (e.g. Union, Xor)
    // this function can perform a range check and throw an unsupported-exception.
    // e.g. if (rgnOp != kIntersect && rgnOp != kDifference) throw...

    // Skia now takes a different type, SkClipOp, as the parameter to clipping calls
    // This type is binary compatible with SkRegion::Op, so a static_cast<> is safe.
    return static_cast<SkClipOp>(rgnOp);
}

static jboolean clipRect(JNIEnv*, jobject, jlong canvasHandle, jfloat l, jfloat t,
                         jfloat r, jfloat b, jint opHandle) {
    SkRegion::Op op = static_cast<SkRegion::Op>(opHandle);
    bool nonEmptyClip = get_canvas(canvasHandle)->clipRect(l, t, r, b, op);
    bool nonEmptyClip = get_canvas(canvasHandle)->clipRect(l, t, r, b,
            opHandleToClipOp(opHandle));
    return nonEmptyClip ? JNI_TRUE : JNI_FALSE;
}

static jboolean clipPath(JNIEnv* env, jobject, jlong canvasHandle, jlong pathHandle,
                         jint opHandle) {
    SkPath* path = reinterpret_cast<SkPath*>(pathHandle);
    SkRegion::Op op = static_cast<SkRegion::Op>(opHandle);
    bool nonEmptyClip = get_canvas(canvasHandle)->clipPath(path, op);
    bool nonEmptyClip = get_canvas(canvasHandle)->clipPath(path, opHandleToClipOp(opHandle));
    return nonEmptyClip ? JNI_TRUE : JNI_FALSE;
}

static jboolean clipRegion(JNIEnv* env, jobject, jlong canvasHandle, jlong deviceRgnHandle,
                           jint opHandle) {
    SkRegion* deviceRgn = reinterpret_cast<SkRegion*>(deviceRgnHandle);
    SkRegion::Op op = static_cast<SkRegion::Op>(opHandle);
    bool nonEmptyClip = get_canvas(canvasHandle)->clipRegion(deviceRgn, op);
    bool nonEmptyClip = get_canvas(canvasHandle)->clipRegion(deviceRgn, opHandleToClipOp(opHandle));
    return nonEmptyClip ? JNI_TRUE : JNI_FALSE;
}

+2 −1
Original line number Diff line number Diff line
@@ -196,7 +196,8 @@ static jboolean android_view_GraphicBuffer_lockCanvas(JNIEnv* env, jobject,

    Canvas* nativeCanvas = GraphicsJNI::getNativeCanvas(env, canvas);
    nativeCanvas->setBitmap(bitmap);
    nativeCanvas->clipRect(rect.left, rect.top, rect.right, rect.bottom);
    nativeCanvas->clipRect(rect.left, rect.top, rect.right, rect.bottom,
            kIntersect_SkClipOp);

    if (dirtyRect) {
        INVOKEV(dirtyRect, gRectClassInfo.set,
+1 −1
Original line number Diff line number Diff line
@@ -339,7 +339,7 @@ static jlong nativeLockCanvas(JNIEnv* env, jclass clazz,

    if (dirtyRectPtr) {
        nativeCanvas->clipRect(dirtyRect.left, dirtyRect.top,
                dirtyRect.right, dirtyRect.bottom);
                dirtyRect.right, dirtyRect.bottom, kIntersect_SkClipOp);
    }

    if (dirtyRectObj) {
+2 −1
Original line number Diff line number Diff line
@@ -166,7 +166,8 @@ static jboolean android_view_TextureView_lockCanvas(JNIEnv* env, jobject,

    Canvas* nativeCanvas = GraphicsJNI::getNativeCanvas(env, canvas);
    nativeCanvas->setBitmap(bitmap);
    nativeCanvas->clipRect(rect.left, rect.top, rect.right, rect.bottom);
    nativeCanvas->clipRect(rect.left, rect.top, rect.right, rect.bottom,
            kIntersect_SkClipOp);

    if (dirtyRect) {
        INVOKEV(dirtyRect, gRectClassInfo.set,
+4 −4
Original line number Diff line number Diff line
@@ -202,17 +202,17 @@ void CanvasState::concatMatrix(const Matrix4& matrix) {
// Clip
///////////////////////////////////////////////////////////////////////////////

bool CanvasState::clipRect(float left, float top, float right, float bottom, SkRegion::Op op) {
bool CanvasState::clipRect(float left, float top, float right, float bottom, SkClipOp op) {
    mSnapshot->clip(Rect(left, top, right, bottom), op);
    return !mSnapshot->clipIsEmpty();
}

bool CanvasState::clipPath(const SkPath* path, SkRegion::Op op) {
bool CanvasState::clipPath(const SkPath* path, SkClipOp op) {
    mSnapshot->clipPath(*path, op);
    return !mSnapshot->clipIsEmpty();
}

bool CanvasState::clipRegion(const SkRegion* region, SkRegion::Op op) {
bool CanvasState::clipRegion(const SkRegion* region, SkClipOp op) {
    mSnapshot->clipRegionTransformed(*region, op);
    return !mSnapshot->clipIsEmpty();
}
@@ -225,7 +225,7 @@ void CanvasState::setClippingOutline(LinearAllocator& allocator, const Outline*
    bool outlineIsRounded = MathUtils::isPositive(radius);
    if (!outlineIsRounded || currentTransform()->isSimple()) {
        // TODO: consider storing this rect separately, so that this can't be replaced with clip ops
        clipRect(bounds.left, bounds.top, bounds.right, bounds.bottom, SkRegion::kIntersect_Op);
        clipRect(bounds.left, bounds.top, bounds.right, bounds.bottom, kIntersect_SkClipOp);
    }
    if (outlineIsRounded) {
        setClippingRoundRect(allocator, bounds, radius, false);
Loading