Example #1
0
SkInterpolatorBase::Result SkInterpolatorBase::timeToT(SkMSec time, SkScalar* T,
                                        int* indexPtr, SkBool* exactPtr) const {
    SkASSERT(fFrameCount > 0);
    Result  result = kNormal_Result;
    if (fRepeat != SK_Scalar1) {
        SkMSec startTime = 0, endTime = 0;  // initialize to avoid warning
        this->getDuration(&startTime, &endTime);
        SkMSec totalTime = endTime - startTime;
        SkMSec offsetTime = time - startTime;
        endTime = SkScalarMulFloor(fRepeat, totalTime);
        if (offsetTime >= endTime) {
            SkScalar fraction = SkScalarFraction(fRepeat);
            offsetTime = fraction == 0 && fRepeat > 0 ? totalTime :
                SkScalarMulFloor(fraction, totalTime);
            result = kFreezeEnd_Result;
        } else {
            int mirror = fFlags & kMirror;
            offsetTime = offsetTime % (totalTime << mirror);
            if (offsetTime > totalTime) { // can only be true if fMirror is true
                offsetTime = (totalTime << 1) - offsetTime;
            }
        }
        time = offsetTime + startTime;
    }

    int index = SkTSearch<SkMSec>(&fTimes[0].fTime, fFrameCount, time,
                                  sizeof(SkTimeCode));

    bool    exact = true;

    if (index < 0) {
        index = ~index;
        if (index == 0) {
            result = kFreezeStart_Result;
        } else if (index == fFrameCount) {
            if (fFlags & kReset) {
                index = 0;
            } else {
                index -= 1;
            }
            result = kFreezeEnd_Result;
        } else {
            exact = false;
        }
    }
    SkASSERT(index < fFrameCount);
    const SkTimeCode* nextTime = &fTimes[index];
    SkMSec   nextT = nextTime[0].fTime;
    if (exact) {
        *T = 0;
    } else {
        SkMSec prevT = nextTime[-1].fTime;
        *T = ComputeRelativeT(time, prevT, nextT, nextTime[-1].fBlend);
    }
    *indexPtr = index;
    *exactPtr = exact;
    return result;
}
Example #2
0
 BlurBench(void* param, SkScalar rad, SkBlurMaskFilter::BlurStyle bs) : INHERITED(param) {
     fRadius = rad;
     fStyle = bs;
     const char* name = rad > 0 ? gStyleName[bs] : "none";
     if (SkScalarFraction(rad) != 0) {
         fName.printf("blur_%.2f_%s", SkScalarToFloat(rad), name);
     } else {
         fName.printf("blur_%d_%s", SkScalarRound(rad), name);
     }
 }
Example #3
0
 MorphologyBench(void* param, SkScalar rad, MorphologyType style)
     :  INHERITED(param) {
     fRadius = rad;
     fStyle = style;
     const char* name = rad > 0 ? gStyleName[style] : "none";
     if (SkScalarFraction(rad) != 0) {
         fName.printf("morph_%.2f_%s", SkScalarToFloat(rad), name);
     } else {
         fName.printf("morph_%d_%s", SkScalarRound(rad), name);
     }
 }
    BlurRectDirectBench(SkScalar rad) : INHERITED(rad) {
        SkString name;

        if (SkScalarFraction(rad) != 0) {
            name.printf("blurrect_direct_%.2f", SkScalarToFloat(rad));
        } else {
            name.printf("blurrect_direct_%d", SkScalarRoundToInt(rad));
        }

        this->setName(name);
    }
Example #5
0
 BlurBench(SkScalar rad, SkBlurStyle bs) {
     fRadius = rad;
     fStyle = bs;
     const char* name = rad > 0 ? gStyleName[bs] : "none";
     const char* quality = "high_quality";
     if (SkScalarFraction(rad) != 0) {
         fName.printf("blur_%.2f_%s_%s", SkScalarToFloat(rad), name, quality);
     } else {
         fName.printf("blur_%d_%s_%s", SkScalarRoundToInt(rad), name, quality);
     }
 }
Example #6
0
 BlurBench(SkScalar rad, SkBlurStyle bs, uint32_t flags = 0) {
     fRadius = rad;
     fStyle = bs;
     fFlags = flags;
     const char* name = rad > 0 ? gStyleName[bs] : "none";
     const char* quality = flags & SkBlurMaskFilter::kHighQuality_BlurFlag ? "high_quality"
                                                                           : "low_quality";
     if (SkScalarFraction(rad) != 0) {
         fName.printf("blur_%.2f_%s_%s", SkScalarToFloat(rad), name, quality);
     } else {
         fName.printf("blur_%d_%s_%s", SkScalarRoundToInt(rad), name, quality);
     }
 }
    bool addPathToAtlas(GrVertexBatch::Target* target,
                        FlushInfo* flushInfo,
                        GrBatchAtlas* atlas,
                        ShapeData* shapeData,
                        const GrShape& shape,
                        bool antiAlias,
                        uint32_t dimension,
                        SkScalar scale) const {
        const SkRect& bounds = shape.bounds();

        // generate bounding rect for bitmap draw
        SkRect scaledBounds = bounds;
        // scale to mip level size
        scaledBounds.fLeft *= scale;
        scaledBounds.fTop *= scale;
        scaledBounds.fRight *= scale;
        scaledBounds.fBottom *= scale;
        // move the origin to an integer boundary (gives better results)
        SkScalar dx = SkScalarFraction(scaledBounds.fLeft);
        SkScalar dy = SkScalarFraction(scaledBounds.fTop);
        scaledBounds.offset(-dx, -dy);
        // get integer boundary
        SkIRect devPathBounds;
        scaledBounds.roundOut(&devPathBounds);
        // pad to allow room for antialiasing
        const int intPad = SkScalarCeilToInt(kAntiAliasPad);
        // pre-move origin (after outset, will be 0,0)
        int width = devPathBounds.width();
        int height = devPathBounds.height();
        devPathBounds.fLeft = intPad;
        devPathBounds.fTop = intPad;
        devPathBounds.fRight = intPad + width;
        devPathBounds.fBottom = intPad + height;
        devPathBounds.outset(intPad, intPad);

        // draw path to bitmap
        SkMatrix drawMatrix;
        drawMatrix.setTranslate(-bounds.left(), -bounds.top());
        drawMatrix.postScale(scale, scale);
        drawMatrix.postTranslate(kAntiAliasPad, kAntiAliasPad);

        // setup bitmap backing
        SkASSERT(devPathBounds.fLeft == 0);
        SkASSERT(devPathBounds.fTop == 0);
        SkAutoPixmapStorage dst;
        if (!dst.tryAlloc(SkImageInfo::MakeA8(devPathBounds.width(),
                                              devPathBounds.height()))) {
            return false;
        }
        sk_bzero(dst.writable_addr(), dst.getSafeSize());

        // rasterize path
        SkPaint paint;
        paint.setStyle(SkPaint::kFill_Style);
        paint.setAntiAlias(antiAlias);

        SkDraw draw;
        sk_bzero(&draw, sizeof(draw));

        SkRasterClip rasterClip;
        rasterClip.setRect(devPathBounds);
        draw.fRC = &rasterClip;
        draw.fMatrix = &drawMatrix;
        draw.fDst = dst;

        SkPath path;
        shape.asPath(&path);
        draw.drawPathCoverage(path, paint);

        // generate signed distance field
        devPathBounds.outset(SK_DistanceFieldPad, SK_DistanceFieldPad);
        width = devPathBounds.width();
        height = devPathBounds.height();
        // TODO We should really generate this directly into the plot somehow
        SkAutoSMalloc<1024> dfStorage(width * height * sizeof(unsigned char));

        // Generate signed distance field
        SkGenerateDistanceFieldFromA8Image((unsigned char*)dfStorage.get(),
                                           (const unsigned char*)dst.addr(),
                                           dst.width(), dst.height(), dst.rowBytes());

        // add to atlas
        SkIPoint16 atlasLocation;
        GrBatchAtlas::AtlasID id;
       if (!atlas->addToAtlas(&id, target, width, height, dfStorage.get(), &atlasLocation)) {
            this->flush(target, flushInfo);
            if (!atlas->addToAtlas(&id, target, width, height, dfStorage.get(), &atlasLocation)) {
                return false;
            }
        }

        // add to cache
        shapeData->fKey.set(shape, dimension);
        shapeData->fScale = scale;
        shapeData->fID = id;
        // change the scaled rect to match the size of the inset distance field
        scaledBounds.fRight = scaledBounds.fLeft +
            SkIntToScalar(devPathBounds.width() - 2*SK_DistanceFieldInset);
        scaledBounds.fBottom = scaledBounds.fTop +
            SkIntToScalar(devPathBounds.height() - 2*SK_DistanceFieldInset);
        // shift the origin to the correct place relative to the distance field
        // need to also restore the fractional translation
        scaledBounds.offset(-SkIntToScalar(SK_DistanceFieldInset) - kAntiAliasPad + dx,
                            -SkIntToScalar(SK_DistanceFieldInset) - kAntiAliasPad + dy);
        shapeData->fBounds = scaledBounds;
        // origin we render from is inset from distance field edge
        atlasLocation.fX += SK_DistanceFieldInset;
        atlasLocation.fY += SK_DistanceFieldInset;
        shapeData->fAtlasLocation = atlasLocation;

        fShapeCache->add(shapeData);
        fShapeList->addToTail(shapeData);
#ifdef DF_PATH_TRACKING
        ++g_NumCachedPaths;
#endif
        return true;
    }
Example #8
0
JSBool SkJSDisplayable::GetProperty(JSContext *cx, JSObject *obj, jsval id,
                                 jsval *vp)
{
    if (JSVAL_IS_INT(id) == 0)
        return JS_TRUE; 
    SkJSDisplayable *p = (SkJSDisplayable *) JS_GetPrivate(cx, obj);
    SkDisplayable* displayable = p->fDisplayable;
    SkDisplayTypes displayableType = displayable->getType();
    int members;
    const SkMemberInfo* info = SkDisplayType::GetMembers(NULL /* fMaker */, displayableType, &members);
    int idIndex = JSVAL_TO_INT(id);
    SkASSERT(idIndex >= 0 && idIndex < members);
    info = &info[idIndex];
    SkDisplayTypes infoType = (SkDisplayTypes) info->fType;
    SkScalar scalar = 0;
    S32 s32 = 0;
    SkString* string= NULL;
    JSString *str;
    if (infoType == SkType_MemberProperty) {
        infoType = info->propertyType();
        switch (infoType) {
            case SkType_Scalar: {
                SkScriptValue scriptValue;
                bool success = displayable->getProperty(info->propertyIndex(), &scriptValue);
                SkASSERT(scriptValue.fType == SkType_Scalar);
                scalar = scriptValue.fOperand.fScalar;
                } break;
            default:
                SkASSERT(0); // !!! unimplemented
        }
    } else {
        SkASSERT(info->fCount == 1);
        switch (infoType) {
            case SkType_Boolean:
            case SkType_Color:
            case SkType_S32:
                s32 = *(S32*) info->memberData(displayable);
                break;
            case SkType_String:
                info->getString(displayable, &string);
                break;
            case SkType_Scalar:
                SkOperand operand;
                info->getValue(displayable, &operand, 1);
                scalar = operand.fScalar;
                break;
            default:
                SkASSERT(0); // !!! unimplemented
        }
    }
    switch (infoType) {
        case SkType_Boolean:
            *vp = BOOLEAN_TO_JSVAL(s32);
            break;
        case SkType_Color:
        case SkType_S32:
            *vp = INT_TO_JSVAL(s32);
            break;
        case SkType_Scalar:
            if (SkScalarFraction(scalar) == 0)
                *vp = INT_TO_JSVAL(SkScalarFloor(scalar));
            else
#ifdef SK_SCALAR_IS_FLOAT
            *vp = DOUBLE_TO_JSVAL(scalar);
#else
            *vp = DOUBLE_TO_JSVAL(scalar / 65536.0f );
#endif
            break;
        case SkType_String:
            str = JS_NewStringCopyN(cx, string->c_str(), string->size());
            *vp = STRING_TO_JSVAL(str);
            break;
        default:
            SkASSERT(0); // !!! unimplemented
    }
    return JS_TRUE;
}