Пример #1
0
// Fold the saveLayer's alpha into the drawBitmapRect and remove the saveLayer
// and restore
static void apply_0(SkDebugCanvas* canvas, int curCommand) {
    SkSaveLayerCommand* saveLayer =
        (SkSaveLayerCommand*) canvas->getDrawCommandAt(curCommand);
    const SkPaint* saveLayerPaint = saveLayer->paint();

    // if (NULL == saveLayerPaint) the dbmr's paint doesn't need to be changed
    if (NULL != saveLayerPaint) {
        SkDrawBitmapRectCommand* dbmr =
            (SkDrawBitmapRectCommand*) canvas->getDrawCommandAt(curCommand+1);
        SkPaint* dbmrPaint = dbmr->paint();

        if (NULL == dbmrPaint) {
            // if the DBMR doesn't have a paint just use the saveLayer's
            dbmr->setPaint(*saveLayerPaint);
        } else if (NULL != saveLayerPaint) {
            // Both paints are present so their alphas need to be combined
            SkColor color = saveLayerPaint->getColor();
            int a0 = SkColorGetA(color);

            color = dbmrPaint->getColor();
            int a1 = SkColorGetA(color);

            int newA = SkMulDiv255Round(a0, a1);
            SkASSERT(newA <= 0xFF);

            SkColor newColor = SkColorSetA(color, newA);
            dbmrPaint->setColor(newColor);
        }
    }

    canvas->deleteDrawCommandAt(curCommand+2);  // restore
    canvas->deleteDrawCommandAt(curCommand);    // saveLayer
}
Пример #2
0
// Check for:
//    SAVE_LAYER
//        SAVE
//            CLIP_RECT
//            DRAW_BITMAP_RECT_TO_RECT
//        RESTORE
//    RESTORE
// where the saveLayer's color can be moved into the drawBitmapRect
static bool check_1(SkDebugCanvas* canvas, int curCommand) {
    if (SAVE_LAYER != canvas->getDrawCommandAt(curCommand)->getType() ||
        canvas->getSize() <= curCommand+5 ||
        SAVE != canvas->getDrawCommandAt(curCommand+1)->getType() ||
        CLIP_RECT != canvas->getDrawCommandAt(curCommand+2)->getType() ||
        DRAW_BITMAP_RECT_TO_RECT != canvas->getDrawCommandAt(curCommand+3)->getType() ||
        RESTORE != canvas->getDrawCommandAt(curCommand+4)->getType() ||
        RESTORE != canvas->getDrawCommandAt(curCommand+5)->getType()) {
        return false;
    }

    SkSaveLayerCommand* saveLayer =
        (SkSaveLayerCommand*) canvas->getDrawCommandAt(curCommand);
    SkDrawBitmapRectCommand* dbmr =
        (SkDrawBitmapRectCommand*) canvas->getDrawCommandAt(curCommand+3);

    const SkPaint* saveLayerPaint = saveLayer->paint();
    SkPaint* dbmrPaint = dbmr->paint();

    // For this optimization we only fold the saveLayer and drawBitmapRect
    // together if the saveLayer's draw is simple (i.e., no fancy effects) and
    // and the only difference in the colors is that the saveLayer's can have
    // an alpha while the drawBitmapRect's is opaque.
    // TODO: it should be possible to fold them together even if they both
    // have different non-255 alphas but this is low priority since we have
    // never seen that case
    // If either operation lacks a paint then the collapse is trivial
    SkColor layerColor = saveLayerPaint->getColor() | 0xFF000000; // force opaque

    return NULL == saveLayerPaint ||
           NULL == dbmrPaint ||
           (is_simple(*saveLayerPaint) && dbmrPaint->getColor() == layerColor);
}
Пример #3
0
// Check for:
//    SAVE_LAYER
//        DRAW_BITMAP_RECT_TO_RECT
//    RESTORE
// where the saveLayer's color can be moved into the drawBitmapRect
static bool check_0(SkDebugCanvas* canvas, int curCommand) {
    if (SAVE_LAYER != canvas->getDrawCommandAt(curCommand)->getType() ||
        canvas->getSize() <= curCommand+2 ||
        DRAW_BITMAP_RECT_TO_RECT != canvas->getDrawCommandAt(curCommand+1)->getType() ||
        RESTORE != canvas->getDrawCommandAt(curCommand+2)->getType()) {
        return false;
    }

    SkSaveLayerCommand* saveLayer =
        (SkSaveLayerCommand*) canvas->getDrawCommandAt(curCommand);
    SkDrawBitmapRectCommand* dbmr =
        (SkDrawBitmapRectCommand*) canvas->getDrawCommandAt(curCommand+1);

    const SkPaint* saveLayerPaint = saveLayer->paint();
    SkPaint* dbmrPaint = dbmr->paint();

    // For this optimization we only fold the saveLayer and drawBitmapRect
    // together if the saveLayer's draw is simple (i.e., no fancy effects)
    // and the only difference in the colors is their alpha value
    SkColor layerColor = saveLayerPaint->getColor() | 0xFF000000; // force opaque
    SkColor dbmrColor = dbmrPaint->getColor() | 0xFF000000;       // force opaque

    // If either operation lacks a paint then the collapse is trivial
    return NULL == saveLayerPaint ||
           NULL == dbmrPaint ||
           (is_simple(*saveLayerPaint) && dbmrColor == layerColor);
}
Пример #4
0
// Fold the clipRect into the drawBitmapRectToRect's src and dest rects
static void apply_8(SkDebugCanvas* canvas, int curCommand) {
    SkClipRectCommand* clip =
        (SkClipRectCommand*) canvas->getDrawCommandAt(curCommand+1);
    SkDrawBitmapRectCommand* dbmr =
        (SkDrawBitmapRectCommand*) canvas->getDrawCommandAt(curCommand+2);

    SkScalar newSrcLeft, newSrcTop;

    if (NULL != dbmr->srcRect()) {
        newSrcLeft = dbmr->srcRect()->fLeft + clip->rect().fLeft - dbmr->dstRect().fLeft;
        newSrcTop  = dbmr->srcRect()->fTop + clip->rect().fTop - dbmr->dstRect().fTop;
    } else {
        newSrcLeft = clip->rect().fLeft - dbmr->dstRect().fLeft;
        newSrcTop  = clip->rect().fTop - dbmr->dstRect().fTop;
    }

    SkRect newSrc = SkRect::MakeXYWH(newSrcLeft, newSrcTop,
                                     clip->rect().width(), clip->rect().height());

    dbmr->setSrcRect(newSrc);
    dbmr->setDstRect(clip->rect());

    // remove everything except the drawbitmaprect
    canvas->deleteDrawCommandAt(curCommand+3);
    canvas->deleteDrawCommandAt(curCommand+1);
    canvas->deleteDrawCommandAt(curCommand);
}
Пример #5
0
// Check for:
//    SAVE
//        CLIP_RECT
//        DRAW_BITMAP_RECT_TO_RECT
//    RESTORE
// where the rect and drawBitmapRect dst exactly match
static bool check_4(SkDebugCanvas* canvas, int curCommand) {
    if (SAVE != canvas->getDrawCommandAt(curCommand)->getType() ||
        canvas->getSize() <= curCommand+4 ||
        CLIP_RECT != canvas->getDrawCommandAt(curCommand+1)->getType() ||
        DRAW_BITMAP_RECT_TO_RECT != canvas->getDrawCommandAt(curCommand+2)->getType() ||
        RESTORE != canvas->getDrawCommandAt(curCommand+3)->getType()) {
        return false;
    }

    SkClipRectCommand* cr =
        (SkClipRectCommand*) canvas->getDrawCommandAt(curCommand+1);
    SkDrawBitmapRectCommand* dbmr  =
        (SkDrawBitmapRectCommand*) canvas->getDrawCommandAt(curCommand+2);

    if (SkRegion::kIntersect_Op != cr->op()) {
        return false;
    }

    return dbmr->dstRect() == cr->rect();
}
Пример #6
0
// Check for:
//    SAVE
//        CLIP_RECT
//        DRAW_BITMAP_RECT_TO_RECT
//    RESTORE
// where the rect and drawBitmapRect dst exactly match
static bool check_4(SkDebugCanvas* canvas, int curCommand) {
    if (SkDrawCommand::kSave_OpType != canvas->getDrawCommandAt(curCommand)->getType() ||
        canvas->getSize() <= curCommand+4 ||
        SkDrawCommand::kClipRect_OpType != canvas->getDrawCommandAt(curCommand+1)->getType() ||
        SkDrawCommand::kDrawBitmapRect_OpType != canvas->getDrawCommandAt(curCommand+2)->getType() ||
        SkDrawCommand::kRestore_OpType != canvas->getDrawCommandAt(curCommand+3)->getType()) {
        return false;
    }

    SkClipRectCommand* cr =
        (SkClipRectCommand*) canvas->getDrawCommandAt(curCommand+1);
    SkDrawBitmapRectCommand* dbmr  =
        (SkDrawBitmapRectCommand*) canvas->getDrawCommandAt(curCommand+2);

    if (SkRegion::kIntersect_Op != cr->op()) {
        return false;
    }

    return dbmr->dstRect() == cr->rect();
}
Пример #7
0
// Fold the saveLayer's alpha into the drawBitmapRect and remove the saveLayer
// and restore
static void apply_1(SkDebugCanvas* canvas, int curCommand) {
    SkSaveLayerCommand* saveLayer =
        (SkSaveLayerCommand*) canvas->getDrawCommandAt(curCommand);
    const SkPaint* saveLayerPaint = saveLayer->paint();

    // if (NULL == saveLayerPaint) the dbmr's paint doesn't need to be changed
    if (NULL != saveLayerPaint) {
        SkDrawBitmapRectCommand* dbmr =
            (SkDrawBitmapRectCommand*) canvas->getDrawCommandAt(curCommand+3);
        SkPaint* dbmrPaint = dbmr->paint();

        if (NULL == dbmrPaint) {
            dbmr->setPaint(*saveLayerPaint);
        } else {
            SkColor newColor = SkColorSetA(dbmrPaint->getColor(),
                                           SkColorGetA(saveLayerPaint->getColor()));
            dbmrPaint->setColor(newColor);
        }
    }

    canvas->deleteDrawCommandAt(curCommand+5);    // restore
    canvas->deleteDrawCommandAt(curCommand);      // saveLayer
}
Пример #8
0
// Check for:
//    SAVE
//       CLIP_RECT
//       DRAWBITMAPRECTTORECT
//    RESTORE
// where:
//      the drawBitmapRectToRect is a 1-1 copy from src to dest
//      the clip rect is BW and a subset of the drawBitmapRectToRect's dest rect
static bool check_8(SkDebugCanvas* canvas, int curCommand) {
    if (SAVE != canvas->getDrawCommandAt(curCommand)->getType() ||
        canvas->getSize() <= curCommand+4 ||
        CLIP_RECT != canvas->getDrawCommandAt(curCommand+1)->getType() ||
        DRAW_BITMAP_RECT_TO_RECT != canvas->getDrawCommandAt(curCommand+2)->getType() ||
        RESTORE != canvas->getDrawCommandAt(curCommand+3)->getType()) {
        return false;
    }

    SkClipRectCommand* clip =
        (SkClipRectCommand*) canvas->getDrawCommandAt(curCommand+1);
    SkDrawBitmapRectCommand* dbmr =
        (SkDrawBitmapRectCommand*) canvas->getDrawCommandAt(curCommand+2);

    if (clip->doAA() || SkRegion::kIntersect_Op != clip->op()) {
        return false;
    }

    // The src->dest mapping needs to be 1-to-1
    if (NULL == dbmr->srcRect()) {
        if (dbmr->bitmap().width() != dbmr->dstRect().width() ||
            dbmr->bitmap().height() != dbmr->dstRect().height()) {
            return false;
        }
    } else {
        if (dbmr->srcRect()->width() != dbmr->dstRect().width() ||
            dbmr->srcRect()->height() != dbmr->dstRect().height()) {
            return false;
        }
    }

    if (!dbmr->dstRect().contains(clip->rect())) {
        return false;
    }

    return true;
}
Пример #9
0
// Reduce to a single drawBitmapRectToRect call by folding the clipRect's into
// the src and dst Rects and the saveLayer paints into the drawBitmapRectToRect's
// paint.
static void apply_7(SkDebugCanvas* canvas, int curCommand) {
    SkSaveLayerCommand* saveLayer0 =
        (SkSaveLayerCommand*) canvas->getDrawCommandAt(curCommand+2);
    SkSaveLayerCommand* saveLayer1 =
        (SkSaveLayerCommand*) canvas->getDrawCommandAt(curCommand+5);
    SkClipRectCommand* clip2 =
        (SkClipRectCommand*) canvas->getDrawCommandAt(curCommand+7);
    SkDrawBitmapRectCommand* dbmr =
        (SkDrawBitmapRectCommand*) canvas->getDrawCommandAt(curCommand+8);

    SkScalar newSrcLeft = dbmr->srcRect()->fLeft + clip2->rect().fLeft - dbmr->dstRect().fLeft;
    SkScalar newSrcTop = dbmr->srcRect()->fTop + clip2->rect().fTop - dbmr->dstRect().fTop;

    SkRect newSrc = SkRect::MakeXYWH(newSrcLeft, newSrcTop,
                                     clip2->rect().width(), clip2->rect().height());

    dbmr->setSrcRect(newSrc);
    dbmr->setDstRect(clip2->rect());

    SkColor color = 0xFF000000;
    int a0, a1;

    const SkPaint* saveLayerPaint0 = saveLayer0->paint();
    if (NULL != saveLayerPaint0) {
        color = saveLayerPaint0->getColor();
        a0 = SkColorGetA(color);
    } else {
        a0 = 0xFF;
    }

    const SkPaint* saveLayerPaint1 = saveLayer1->paint();
    if (NULL != saveLayerPaint1) {
        color = saveLayerPaint1->getColor();
        a1 = SkColorGetA(color);
    } else {
        a1 = 0xFF;
    }

    int newA = SkMulDiv255Round(a0, a1);
    SkASSERT(newA <= 0xFF);

    SkPaint* dbmrPaint = dbmr->paint();

    if (NULL != dbmrPaint) {
        SkColor newColor = SkColorSetA(dbmrPaint->getColor(), newA);
        dbmrPaint->setColor(newColor);
    } else {
        SkColor newColor = SkColorSetA(color, newA);

        SkPaint newPaint;
        newPaint.setColor(newColor);
        dbmr->setPaint(newPaint);
    }

    // remove everything except the drawbitmaprect
    canvas->deleteDrawCommandAt(curCommand+13);   // restore
    canvas->deleteDrawCommandAt(curCommand+12);   // restore
    canvas->deleteDrawCommandAt(curCommand+11);   // restore
    canvas->deleteDrawCommandAt(curCommand+10);   // restore
    canvas->deleteDrawCommandAt(curCommand+9);    // restore
    canvas->deleteDrawCommandAt(curCommand+7);    // clipRect
    canvas->deleteDrawCommandAt(curCommand+6);    // save
    canvas->deleteDrawCommandAt(curCommand+5);    // saveLayer
    canvas->deleteDrawCommandAt(curCommand+4);    // clipRect
    canvas->deleteDrawCommandAt(curCommand+3);    // save
    canvas->deleteDrawCommandAt(curCommand+2);    // saveLayer
    canvas->deleteDrawCommandAt(curCommand+1);    // clipRect
    canvas->deleteDrawCommandAt(curCommand);      // save
}
Пример #10
0
// Check for:
//  SAVE
//      CLIP_RECT
//      SAVE_LAYER
//          SAVE
//              CLIP_RECT
//              SAVE_LAYER
//                  SAVE
//                      CLIP_RECT
//                      DRAWBITMAPRECTTORECT
//                  RESTORE
//              RESTORE
//          RESTORE
//      RESTORE
//  RESTORE
// where:
//      all the clipRect's are BW, nested, intersections
//      the drawBitmapRectToRect is a 1-1 copy from src to dest
//      the last (smallest) clip rect is a subset of the drawBitmapRectToRect's dest rect
//      all the saveLayer's paints can be rolled into the drawBitmapRectToRect's paint
// This pattern is used by Google spreadsheet when drawing the toolbar buttons
static bool check_7(SkDebugCanvas* canvas, int curCommand) {
    if (SAVE != canvas->getDrawCommandAt(curCommand)->getType() ||
        canvas->getSize() <= curCommand+13 ||
        CLIP_RECT != canvas->getDrawCommandAt(curCommand+1)->getType() ||
        SAVE_LAYER != canvas->getDrawCommandAt(curCommand+2)->getType() ||
        SAVE != canvas->getDrawCommandAt(curCommand+3)->getType() ||
        CLIP_RECT != canvas->getDrawCommandAt(curCommand+4)->getType() ||
        SAVE_LAYER != canvas->getDrawCommandAt(curCommand+5)->getType() ||
        SAVE != canvas->getDrawCommandAt(curCommand+6)->getType() ||
        CLIP_RECT != canvas->getDrawCommandAt(curCommand+7)->getType() ||
        DRAW_BITMAP_RECT_TO_RECT != canvas->getDrawCommandAt(curCommand+8)->getType() ||
        RESTORE != canvas->getDrawCommandAt(curCommand+9)->getType() ||
        RESTORE != canvas->getDrawCommandAt(curCommand+10)->getType() ||
        RESTORE != canvas->getDrawCommandAt(curCommand+11)->getType() ||
        RESTORE != canvas->getDrawCommandAt(curCommand+12)->getType() ||
        RESTORE != canvas->getDrawCommandAt(curCommand+13)->getType()) {
        return false;
    }

    SkClipRectCommand* clip0 =
        (SkClipRectCommand*) canvas->getDrawCommandAt(curCommand+1);
    SkSaveLayerCommand* saveLayer0 =
        (SkSaveLayerCommand*) canvas->getDrawCommandAt(curCommand+2);
    SkClipRectCommand* clip1 =
        (SkClipRectCommand*) canvas->getDrawCommandAt(curCommand+4);
    SkSaveLayerCommand* saveLayer1 =
        (SkSaveLayerCommand*) canvas->getDrawCommandAt(curCommand+5);
    SkClipRectCommand* clip2 =
        (SkClipRectCommand*) canvas->getDrawCommandAt(curCommand+7);
    SkDrawBitmapRectCommand* dbmr =
        (SkDrawBitmapRectCommand*) canvas->getDrawCommandAt(curCommand+8);

    if (clip0->doAA() || clip1->doAA() || clip2->doAA()) {
        return false;
    }

    if (SkRegion::kIntersect_Op != clip0->op() ||
        SkRegion::kIntersect_Op != clip1->op() ||
        SkRegion::kIntersect_Op != clip2->op()) {
        return false;
    }

    if (!clip0->rect().contains(clip1->rect()) ||
        !clip1->rect().contains(clip2->rect())) {
        return false;
    }

    // The src->dest mapping needs to be 1-to-1
    if (NULL == dbmr->srcRect()) {
        if (dbmr->bitmap().width() != dbmr->dstRect().width() ||
            dbmr->bitmap().height() != dbmr->dstRect().height()) {
            return false;
        }
    } else {
        if (dbmr->srcRect()->width() != dbmr->dstRect().width() ||
            dbmr->srcRect()->height() != dbmr->dstRect().height()) {
            return false;
        }
    }

    if (!dbmr->dstRect().contains(clip2->rect())) {
        return false;
    }

    const SkPaint* saveLayerPaint0 = saveLayer0->paint();
    const SkPaint* saveLayerPaint1 = saveLayer1->paint();

    if ((NULL != saveLayerPaint0 && !is_simple(*saveLayerPaint0)) ||
        (NULL != saveLayerPaint1 && !is_simple(*saveLayerPaint1))) {
        return false;
    }

    SkPaint* dbmrPaint = dbmr->paint();

    if (NULL == dbmrPaint) {
        return true;
    }

    if (NULL != saveLayerPaint0) {
        SkColor layerColor0 = saveLayerPaint0->getColor() | 0xFF000000; // force opaque
        if (dbmrPaint->getColor() != layerColor0) {
            return false;
        }
    }

    if (NULL != saveLayerPaint1) {
        SkColor layerColor1 = saveLayerPaint1->getColor() | 0xFF000000; // force opaque
        if (dbmrPaint->getColor() != layerColor1) {
            return false;
        }
    }

    return true;
}