Index: tools/filtermain.cpp |
diff --git a/tools/filtermain.cpp b/tools/filtermain.cpp |
deleted file mode 100644 |
index 24f0c78c02de376c0352e951e7508c53ba149d49..0000000000000000000000000000000000000000 |
--- a/tools/filtermain.cpp |
+++ /dev/null |
@@ -1,804 +0,0 @@ |
-/* |
- * Copyright 2012 Google Inc. |
- * |
- * Use of this source code is governed by a BSD-style license that can be |
- * found in the LICENSE file. |
- */ |
- |
-#include "SkDebugCanvas.h" |
-#include "SkDevice.h" |
-#include "SkForceLinking.h" |
-#include "SkGraphics.h" |
-#include "SkImageDecoder.h" |
-#include "SkImageEncoder.h" |
-#include "SkOSFile.h" |
-#include "SkPicture.h" |
-#include "SkPictureRecord.h" |
-#include "SkPictureRecorder.h" |
-#include "SkStream.h" |
-#include "picture_utils.h" |
- |
-__SK_FORCE_IMAGE_DECODER_LINKING; |
- |
-static void usage() { |
- SkDebugf("Usage: filter -i inFile [-o outFile] [--input-dir path] [--output-dir path]\n"); |
- SkDebugf(" [-h|--help]\n\n"); |
- SkDebugf(" -i inFile : file to filter.\n"); |
- SkDebugf(" -o outFile : result of filtering.\n"); |
- SkDebugf(" --input-dir : process all files in dir with .skp extension.\n"); |
- SkDebugf(" --output-dir : results of filtering the input dir.\n"); |
- SkDebugf(" -h|--help : Show this help message.\n"); |
-} |
- |
-// Is the supplied paint simply a color? |
-static bool is_simple(const SkPaint& p) { |
- return nullptr == p.getPathEffect() && |
- nullptr == p.getShader() && |
- nullptr == p.getXfermode() && |
- nullptr == p.getMaskFilter() && |
- nullptr == p.getColorFilter() && |
- nullptr == p.getRasterizer() && |
- nullptr == p.getLooper() && |
- nullptr == p.getImageFilter(); |
-} |
- |
- |
-// 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 (SkDrawCommand::kSaveLayer_OpType != canvas->getDrawCommandAt(curCommand)->getType() || |
- canvas->getSize() <= curCommand+2 || |
- SkDrawCommand::kDrawBitmapRect_OpType != canvas->getDrawCommandAt(curCommand+1)->getType() || |
- SkDrawCommand::kRestore_OpType != 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 nullptr == saveLayerPaint || |
- nullptr == dbmrPaint || |
- (is_simple(*saveLayerPaint) && dbmrColor == layerColor); |
-} |
- |
-// 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 (nullptr == saveLayerPaint) the dbmr's paint doesn't need to be changed |
- if (saveLayerPaint) { |
- SkDrawBitmapRectCommand* dbmr = |
- (SkDrawBitmapRectCommand*) canvas->getDrawCommandAt(curCommand+1); |
- SkPaint* dbmrPaint = dbmr->paint(); |
- |
- if (nullptr == dbmrPaint) { |
- // if the DBMR doesn't have a paint just use the saveLayer's |
- dbmr->setPaint(*saveLayerPaint); |
- } else if (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 |
-} |
- |
-// 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 (SkDrawCommand::kSaveLayer_OpType != canvas->getDrawCommandAt(curCommand)->getType() || |
- canvas->getSize() <= curCommand+5 || |
- SkDrawCommand::kSave_OpType != canvas->getDrawCommandAt(curCommand+1)->getType() || |
- SkDrawCommand::kClipRect_OpType != canvas->getDrawCommandAt(curCommand+2)->getType() || |
- SkDrawCommand::kDrawBitmapRect_OpType != canvas->getDrawCommandAt(curCommand+3)->getType() || |
- SkDrawCommand::kRestore_OpType != canvas->getDrawCommandAt(curCommand+4)->getType() || |
- SkDrawCommand::kRestore_OpType != 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 nullptr == saveLayerPaint || |
- nullptr == dbmrPaint || |
- (is_simple(*saveLayerPaint) && dbmrPaint->getColor() == layerColor); |
-} |
- |
-// 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 (nullptr == saveLayerPaint) the dbmr's paint doesn't need to be changed |
- if (saveLayerPaint) { |
- SkDrawBitmapRectCommand* dbmr = |
- (SkDrawBitmapRectCommand*) canvas->getDrawCommandAt(curCommand+3); |
- SkPaint* dbmrPaint = dbmr->paint(); |
- |
- if (nullptr == 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 |
-} |
- |
-// Check for: |
-// SAVE |
-// CLIP_RECT |
-// DRAW_RECT |
-// RESTORE |
-// where the rect is entirely within the clip and the clip is an intersect |
-static bool check_2(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::kDrawRect_OpType != canvas->getDrawCommandAt(curCommand+2)->getType() || |
- SkDrawCommand::kRestore_OpType != canvas->getDrawCommandAt(curCommand+3)->getType()) { |
- return false; |
- } |
- |
- SkClipRectCommand* cr = |
- (SkClipRectCommand*) canvas->getDrawCommandAt(curCommand+1); |
- SkDrawRectCommand* dr = |
- (SkDrawRectCommand*) canvas->getDrawCommandAt(curCommand+2); |
- |
- if (SkRegion::kIntersect_Op != cr->op()) { |
- return false; |
- } |
- |
- return cr->rect().contains(dr->rect()); |
-} |
- |
-// Remove everything but the drawRect |
-static void apply_2(SkDebugCanvas* canvas, int curCommand) { |
- canvas->deleteDrawCommandAt(curCommand+3); // restore |
- // drawRect |
- canvas->deleteDrawCommandAt(curCommand+1); // clipRect |
- canvas->deleteDrawCommandAt(curCommand); // save |
-} |
- |
-// Check for: |
-// SAVE |
-// CLIP_RRECT |
-// DRAW_RECT |
-// RESTORE |
-// where the rect entirely encloses the clip |
-static bool check_3(SkDebugCanvas* canvas, int curCommand) { |
- if (SkDrawCommand::kSave_OpType != canvas->getDrawCommandAt(curCommand)->getType() || |
- canvas->getSize() <= curCommand+4 || |
- SkDrawCommand::kClipRRect_OpType != canvas->getDrawCommandAt(curCommand+1)->getType() || |
- SkDrawCommand::kDrawRect_OpType != canvas->getDrawCommandAt(curCommand+2)->getType() || |
- SkDrawCommand::kRestore_OpType != canvas->getDrawCommandAt(curCommand+3)->getType()) { |
- return false; |
- } |
- |
- SkClipRRectCommand* crr = |
- (SkClipRRectCommand*) canvas->getDrawCommandAt(curCommand+1); |
- SkDrawRectCommand* dr = |
- (SkDrawRectCommand*) canvas->getDrawCommandAt(curCommand+2); |
- |
- if (SkRegion::kIntersect_Op != crr->op()) { |
- return false; |
- } |
- |
- return dr->rect().contains(crr->rrect().rect()); |
-} |
- |
-// Replace everything with a drawRRect with the paint from the drawRect |
-// and the AA settings from the clipRRect |
-static void apply_3(SkDebugCanvas* canvas, int curCommand) { |
- |
- canvas->deleteDrawCommandAt(curCommand+3); // restore |
- |
- SkClipRRectCommand* crr = |
- (SkClipRRectCommand*) canvas->getDrawCommandAt(curCommand+1); |
- SkDrawRectCommand* dr = |
- (SkDrawRectCommand*) canvas->getDrawCommandAt(curCommand+2); |
- |
- // TODO: could skip paint re-creation if the AA settings already match |
- SkPaint newPaint = dr->paint(); |
- newPaint.setAntiAlias(crr->doAA()); |
- SkDrawRRectCommand* drr = new SkDrawRRectCommand(crr->rrect(), newPaint); |
- canvas->setDrawCommandAt(curCommand+2, drr); |
- |
- canvas->deleteDrawCommandAt(curCommand+1); // clipRRect |
- canvas->deleteDrawCommandAt(curCommand); // save |
-} |
- |
-// 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(); |
-} |
- |
-// Remove everything but the drawBitmapRect |
-static void apply_4(SkDebugCanvas* canvas, int curCommand) { |
- canvas->deleteDrawCommandAt(curCommand+3); // restore |
- // drawBitmapRectToRect |
- canvas->deleteDrawCommandAt(curCommand+1); // clipRect |
- canvas->deleteDrawCommandAt(curCommand); // save |
-} |
- |
-// 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 (SkDrawCommand::kSave_OpType != canvas->getDrawCommandAt(curCommand)->getType() || |
- canvas->getSize() <= curCommand+13 || |
- SkDrawCommand::kClipRect_OpType != canvas->getDrawCommandAt(curCommand+1)->getType() || |
- SkDrawCommand::kSaveLayer_OpType != canvas->getDrawCommandAt(curCommand+2)->getType() || |
- SkDrawCommand::kSave_OpType != canvas->getDrawCommandAt(curCommand+3)->getType() || |
- SkDrawCommand::kClipRect_OpType != canvas->getDrawCommandAt(curCommand+4)->getType() || |
- SkDrawCommand::kSaveLayer_OpType != canvas->getDrawCommandAt(curCommand+5)->getType() || |
- SkDrawCommand::kSave_OpType != canvas->getDrawCommandAt(curCommand+6)->getType() || |
- SkDrawCommand::kClipRect_OpType != canvas->getDrawCommandAt(curCommand+7)->getType() || |
- SkDrawCommand::kDrawBitmapRect_OpType != canvas->getDrawCommandAt(curCommand+8)->getType() || |
- SkDrawCommand::kRestore_OpType != canvas->getDrawCommandAt(curCommand+9)->getType() || |
- SkDrawCommand::kRestore_OpType != canvas->getDrawCommandAt(curCommand+10)->getType() || |
- SkDrawCommand::kRestore_OpType != canvas->getDrawCommandAt(curCommand+11)->getType() || |
- SkDrawCommand::kRestore_OpType != canvas->getDrawCommandAt(curCommand+12)->getType() || |
- SkDrawCommand::kRestore_OpType != 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 (nullptr == 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 ((saveLayerPaint0 && !is_simple(*saveLayerPaint0)) || |
- (saveLayerPaint1 && !is_simple(*saveLayerPaint1))) { |
- return false; |
- } |
- |
- SkPaint* dbmrPaint = dbmr->paint(); |
- |
- if (nullptr == dbmrPaint) { |
- return true; |
- } |
- |
- if (saveLayerPaint0) { |
- SkColor layerColor0 = saveLayerPaint0->getColor() | 0xFF000000; // force opaque |
- if (dbmrPaint->getColor() != layerColor0) { |
- return false; |
- } |
- } |
- |
- if (saveLayerPaint1) { |
- SkColor layerColor1 = saveLayerPaint1->getColor() | 0xFF000000; // force opaque |
- if (dbmrPaint->getColor() != layerColor1) { |
- return false; |
- } |
- } |
- |
- return true; |
-} |
- |
-// 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 (saveLayerPaint0) { |
- color = saveLayerPaint0->getColor(); |
- a0 = SkColorGetA(color); |
- } else { |
- a0 = 0xFF; |
- } |
- |
- const SkPaint* saveLayerPaint1 = saveLayer1->paint(); |
- if (saveLayerPaint1) { |
- color = saveLayerPaint1->getColor(); |
- a1 = SkColorGetA(color); |
- } else { |
- a1 = 0xFF; |
- } |
- |
- int newA = SkMulDiv255Round(a0, a1); |
- SkASSERT(newA <= 0xFF); |
- |
- SkPaint* dbmrPaint = dbmr->paint(); |
- |
- if (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 |
-} |
- |
-// 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 (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* 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 (nullptr == 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; |
-} |
- |
-// 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 (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); |
-} |
- |
-// Check for: |
-// SAVE |
-// CLIP_RECT |
-// DRAWBITMAPRECTTORECT |
-// RESTORE |
-// where: |
-// clipRect is BW and encloses the DBMR2R's dest rect |
-static bool check_9(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* clip = |
- (SkClipRectCommand*) canvas->getDrawCommandAt(curCommand+1); |
- SkDrawBitmapRectCommand* dbmr = |
- (SkDrawBitmapRectCommand*) canvas->getDrawCommandAt(curCommand+2); |
- |
- if (clip->doAA() || SkRegion::kIntersect_Op != clip->op()) { |
- return false; |
- } |
- |
- if (!clip->rect().contains(dbmr->dstRect())) { |
- return false; |
- } |
- |
- return true; |
-} |
- |
-// remove everything except the drawbitmaprect |
-static void apply_9(SkDebugCanvas* canvas, int curCommand) { |
- canvas->deleteDrawCommandAt(curCommand+3); // restore |
- // drawBitmapRectToRect |
- canvas->deleteDrawCommandAt(curCommand+1); // clipRect |
- canvas->deleteDrawCommandAt(curCommand); // save |
-} |
- |
-typedef bool (*PFCheck)(SkDebugCanvas* canvas, int curCommand); |
-typedef void (*PFApply)(SkDebugCanvas* canvas, int curCommand); |
- |
-struct OptTableEntry { |
- PFCheck fCheck; |
- PFApply fApply; |
- int fNumTimesApplied; |
-} gOptTable[] = { |
- { check_0, apply_0, 0 }, |
- { check_1, apply_1, 0 }, |
- { check_2, apply_2, 0 }, |
- { check_3, apply_3, 0 }, |
- { check_4, apply_4, 0 }, |
- { check_7, apply_7, 0 }, |
- { check_8, apply_8, 0 }, |
- { check_9, apply_9, 0 }, |
-}; |
- |
- |
-static int filter_picture(const SkString& inFile, const SkString& outFile) { |
- SkAutoTUnref<SkPicture> inPicture; |
- |
- SkFILEStream inStream(inFile.c_str()); |
- if (inStream.isValid()) { |
- inPicture.reset(SkPicture::CreateFromStream(&inStream)); |
- } |
- |
- if (nullptr == inPicture.get()) { |
- SkDebugf("Could not read file %s\n", inFile.c_str()); |
- return -1; |
- } |
- |
- int localCount[SK_ARRAY_COUNT(gOptTable)]; |
- |
- memset(localCount, 0, sizeof(localCount)); |
- |
- SkDebugCanvas debugCanvas(SkScalarCeilToInt(inPicture->cullRect().width()), |
- SkScalarCeilToInt(inPicture->cullRect().height())); |
- inPicture->playback(&debugCanvas); |
- |
- // delete the initial save and restore since replaying the commands will |
- // re-add them |
- if (debugCanvas.getSize() > 1) { |
- debugCanvas.deleteDrawCommandAt(0); |
- debugCanvas.deleteDrawCommandAt(debugCanvas.getSize()-1); |
- } |
- |
- bool changed = true; |
- int numBefore = debugCanvas.getSize(); |
- |
- while (changed) { |
- changed = false; |
- for (int i = 0; i < debugCanvas.getSize(); ++i) { |
- for (size_t opt = 0; opt < SK_ARRAY_COUNT(gOptTable); ++opt) { |
- if ((*gOptTable[opt].fCheck)(&debugCanvas, i)) { |
- (*gOptTable[opt].fApply)(&debugCanvas, i); |
- |
- ++gOptTable[opt].fNumTimesApplied; |
- ++localCount[opt]; |
- |
- if (debugCanvas.getSize() == i) { |
- // the optimization removed all the remaining operations |
- break; |
- } |
- |
- opt = 0; // try all the opts all over again |
- changed = true; |
- } |
- } |
- } |
- } |
- |
- int numAfter = debugCanvas.getSize(); |
- |
- if (!outFile.isEmpty()) { |
- SkPictureRecorder recorder; |
- SkCanvas* canvas = recorder.beginRecording(inPicture->cullRect().width(), |
- inPicture->cullRect().height(), |
- nullptr, 0); |
- debugCanvas.draw(canvas); |
- SkAutoTUnref<SkPicture> outPicture(recorder.endRecording()); |
- |
- SkFILEWStream outStream(outFile.c_str()); |
- |
- outPicture->serialize(&outStream); |
- } |
- |
- bool someOptFired = false; |
- for (size_t opt = 0; opt < SK_ARRAY_COUNT(gOptTable); ++opt) { |
- if (0 != localCount[opt]) { |
- SkDebugf("%d: %d ", opt, localCount[opt]); |
- someOptFired = true; |
- } |
- } |
- |
- if (!someOptFired) { |
- SkDebugf("No opts fired\n"); |
- } else { |
- SkDebugf("\t before: %d after: %d delta: %d\n", |
- numBefore, numAfter, numBefore-numAfter); |
- } |
- |
- return 0; |
-} |
- |
-// This function is not marked as 'static' so it can be referenced externally |
-// in the iOS build. |
-int tool_main(int argc, char** argv); // suppress a warning on mac |
- |
-int tool_main(int argc, char** argv) { |
- SkGraphics::Init(); |
- |
- if (argc < 3) { |
- usage(); |
- return -1; |
- } |
- |
- SkString inFile, outFile, inDir, outDir; |
- |
- char* const* stop = argv + argc; |
- for (++argv; argv < stop; ++argv) { |
- if (strcmp(*argv, "-i") == 0) { |
- argv++; |
- if (argv < stop && **argv) { |
- inFile.set(*argv); |
- } else { |
- SkDebugf("missing arg for -i\n"); |
- usage(); |
- return -1; |
- } |
- } else if (strcmp(*argv, "--input-dir") == 0) { |
- argv++; |
- if (argv < stop && **argv) { |
- inDir.set(*argv); |
- } else { |
- SkDebugf("missing arg for --input-dir\n"); |
- usage(); |
- return -1; |
- } |
- } else if (strcmp(*argv, "--output-dir") == 0) { |
- argv++; |
- if (argv < stop && **argv) { |
- outDir.set(*argv); |
- } else { |
- SkDebugf("missing arg for --output-dir\n"); |
- usage(); |
- return -1; |
- } |
- } else if (strcmp(*argv, "-o") == 0) { |
- argv++; |
- if (argv < stop && **argv) { |
- outFile.set(*argv); |
- } else { |
- SkDebugf("missing arg for -o\n"); |
- usage(); |
- return -1; |
- } |
- } else if (strcmp(*argv, "--help") == 0 || strcmp(*argv, "-h") == 0) { |
- usage(); |
- return 0; |
- } else { |
- SkDebugf("unknown arg %s\n", *argv); |
- usage(); |
- return -1; |
- } |
- } |
- |
- SkOSFile::Iter iter(inDir.c_str(), "skp"); |
- |
- SkString inputFilename, outputFilename; |
- if (iter.next(&inputFilename)) { |
- |
- do { |
- inFile = SkOSPath::Join(inDir.c_str(), inputFilename.c_str()); |
- if (!outDir.isEmpty()) { |
- outFile = SkOSPath::Join(outDir.c_str(), inputFilename.c_str()); |
- } |
- SkDebugf("Executing %s\n", inputFilename.c_str()); |
- filter_picture(inFile, outFile); |
- } while(iter.next(&inputFilename)); |
- |
- } else if (!inFile.isEmpty()) { |
- filter_picture(inFile, outFile); |
- } else { |
- usage(); |
- return -1; |
- } |
- |
- for (size_t opt = 0; opt < SK_ARRAY_COUNT(gOptTable); ++opt) { |
- SkDebugf("opt %d: %d\n", opt, gOptTable[opt].fNumTimesApplied); |
- } |
- |
- return 0; |
-} |
- |
-#if !defined SK_BUILD_FOR_IOS |
-int main(int argc, char * const argv[]) { |
- return tool_main(argc, (char**) argv); |
-} |
-#endif |