blob: 6883ff2047491d306ce5764c5672186d672ede56 [file] [log] [blame]
robertphillips@google.comc7e4a5a2012-10-04 13:00:33 +00001/*
2 * Copyright 2012 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
robertphillips@google.com3b0a9fe2013-01-31 15:56:22 +00008#include "SkDebugCanvas.h"
robertphillips@google.com801cee12012-10-19 19:06:11 +00009#include "SkDevice.h"
scroggo@google.com7def5e12013-05-31 14:00:10 +000010#include "SkForceLinking.h"
robertphillips@google.comc7e4a5a2012-10-04 13:00:33 +000011#include "SkGraphics.h"
robertphillips@google.com4e4d75b2012-11-12 18:03:19 +000012#include "SkImageDecoder.h"
robertphillips@google.com801cee12012-10-19 19:06:11 +000013#include "SkImageEncoder.h"
djsollen@google.coma09e8832012-11-13 18:50:33 +000014#include "SkOSFile.h"
robertphillips@google.comc7e4a5a2012-10-04 13:00:33 +000015#include "SkPicture.h"
robertphillips2de59392015-02-11 13:18:14 -080016#include "SkPictureRecord.h"
robertphillips@google.com770963f2014-04-18 18:04:41 +000017#include "SkPictureRecorder.h"
robertphillips@google.comc7e4a5a2012-10-04 13:00:33 +000018#include "SkStream.h"
djsollen@google.coma09e8832012-11-13 18:50:33 +000019#include "picture_utils.h"
robertphillips@google.comc7e4a5a2012-10-04 13:00:33 +000020
scroggo@google.com7def5e12013-05-31 14:00:10 +000021__SK_FORCE_IMAGE_DECODER_LINKING;
22
robertphillips@google.comc7e4a5a2012-10-04 13:00:33 +000023static void usage() {
robertphillips@google.comd3d377f2012-12-07 20:56:13 +000024 SkDebugf("Usage: filter -i inFile [-o outFile] [--input-dir path] [--output-dir path]\n");
robertphillips@google.com3b0a9fe2013-01-31 15:56:22 +000025 SkDebugf(" [-h|--help]\n\n");
robertphillips@google.com2e87ba02013-04-08 15:45:30 +000026 SkDebugf(" -i inFile : file to filter.\n");
robertphillips@google.comc7e4a5a2012-10-04 13:00:33 +000027 SkDebugf(" -o outFile : result of filtering.\n");
djsollen@google.coma09e8832012-11-13 18:50:33 +000028 SkDebugf(" --input-dir : process all files in dir with .skp extension.\n");
29 SkDebugf(" --output-dir : results of filtering the input dir.\n");
robertphillips@google.comc7e4a5a2012-10-04 13:00:33 +000030 SkDebugf(" -h|--help : Show this help message.\n");
31}
32
robertphillips@google.com3b0a9fe2013-01-31 15:56:22 +000033// Is the supplied paint simply a color?
34static bool is_simple(const SkPaint& p) {
35 return NULL == p.getPathEffect() &&
36 NULL == p.getShader() &&
37 NULL == p.getXfermode() &&
38 NULL == p.getMaskFilter() &&
39 NULL == p.getColorFilter() &&
40 NULL == p.getRasterizer() &&
41 NULL == p.getLooper() &&
42 NULL == p.getImageFilter();
43}
robertphillips@google.comd3d377f2012-12-07 20:56:13 +000044
robertphillips@google.com50c84da2013-04-01 18:18:49 +000045
robertphillips@google.com73743552013-02-05 20:51:49 +000046// Check for:
47// SAVE_LAYER
48// DRAW_BITMAP_RECT_TO_RECT
49// RESTORE
50// where the saveLayer's color can be moved into the drawBitmapRect
robertphillips@google.com50c84da2013-04-01 18:18:49 +000051static bool check_0(SkDebugCanvas* canvas, int curCommand) {
robertphillips9bafc302015-02-13 11:13:00 -080052 if (SkDrawCommand::kSaveLayer_OpType != canvas->getDrawCommandAt(curCommand)->getType() ||
robertphillips@google.com50c84da2013-04-01 18:18:49 +000053 canvas->getSize() <= curCommand+2 ||
robertphillips9bafc302015-02-13 11:13:00 -080054 SkDrawCommand::kDrawBitmapRect_OpType != canvas->getDrawCommandAt(curCommand+1)->getType() ||
55 SkDrawCommand::kRestore_OpType != canvas->getDrawCommandAt(curCommand+2)->getType()) {
robertphillips@google.com73743552013-02-05 20:51:49 +000056 return false;
robertphillips@google.com50c84da2013-04-01 18:18:49 +000057 }
robertphillips@google.com73743552013-02-05 20:51:49 +000058
commit-bot@chromium.org7a115912013-06-18 20:20:55 +000059 SkSaveLayerCommand* saveLayer =
60 (SkSaveLayerCommand*) canvas->getDrawCommandAt(curCommand);
61 SkDrawBitmapRectCommand* dbmr =
62 (SkDrawBitmapRectCommand*) canvas->getDrawCommandAt(curCommand+1);
robertphillips@google.com73743552013-02-05 20:51:49 +000063
64 const SkPaint* saveLayerPaint = saveLayer->paint();
65 SkPaint* dbmrPaint = dbmr->paint();
66
skia.committer@gmail.com3d18d062013-02-14 07:01:34 +000067 // For this optimization we only fold the saveLayer and drawBitmapRect
robertphillips@google.comc5257042013-04-02 15:30:03 +000068 // together if the saveLayer's draw is simple (i.e., no fancy effects)
69 // and the only difference in the colors is their alpha value
robertphillips@google.com1780a3c2013-02-13 13:27:44 +000070 SkColor layerColor = saveLayerPaint->getColor() | 0xFF000000; // force opaque
robertphillips@google.comc5257042013-04-02 15:30:03 +000071 SkColor dbmrColor = dbmrPaint->getColor() | 0xFF000000; // force opaque
robertphillips@google.com1780a3c2013-02-13 13:27:44 +000072
robertphillips@google.comc5257042013-04-02 15:30:03 +000073 // If either operation lacks a paint then the collapse is trivial
robertphillips@google.com73743552013-02-05 20:51:49 +000074 return NULL == saveLayerPaint ||
75 NULL == dbmrPaint ||
robertphillips@google.comc5257042013-04-02 15:30:03 +000076 (is_simple(*saveLayerPaint) && dbmrColor == layerColor);
robertphillips@google.com73743552013-02-05 20:51:49 +000077}
78
79// Fold the saveLayer's alpha into the drawBitmapRect and remove the saveLayer
80// and restore
robertphillips@google.com50c84da2013-04-01 18:18:49 +000081static void apply_0(SkDebugCanvas* canvas, int curCommand) {
commit-bot@chromium.org7a115912013-06-18 20:20:55 +000082 SkSaveLayerCommand* saveLayer =
83 (SkSaveLayerCommand*) canvas->getDrawCommandAt(curCommand);
robertphillips@google.com73743552013-02-05 20:51:49 +000084 const SkPaint* saveLayerPaint = saveLayer->paint();
robertphillips@google.com73743552013-02-05 20:51:49 +000085
robertphillips@google.com50c84da2013-04-01 18:18:49 +000086 // if (NULL == saveLayerPaint) the dbmr's paint doesn't need to be changed
bsalomon49f085d2014-09-05 13:34:00 -070087 if (saveLayerPaint) {
commit-bot@chromium.org7a115912013-06-18 20:20:55 +000088 SkDrawBitmapRectCommand* dbmr =
89 (SkDrawBitmapRectCommand*) canvas->getDrawCommandAt(curCommand+1);
robertphillips@google.com50c84da2013-04-01 18:18:49 +000090 SkPaint* dbmrPaint = dbmr->paint();
91
92 if (NULL == dbmrPaint) {
93 // if the DBMR doesn't have a paint just use the saveLayer's
94 dbmr->setPaint(*saveLayerPaint);
bsalomon49f085d2014-09-05 13:34:00 -070095 } else if (saveLayerPaint) {
robertphillips@google.comc5257042013-04-02 15:30:03 +000096 // Both paints are present so their alphas need to be combined
97 SkColor color = saveLayerPaint->getColor();
98 int a0 = SkColorGetA(color);
99
100 color = dbmrPaint->getColor();
101 int a1 = SkColorGetA(color);
102
103 int newA = SkMulDiv255Round(a0, a1);
104 SkASSERT(newA <= 0xFF);
105
106 SkColor newColor = SkColorSetA(color, newA);
robertphillips@google.com50c84da2013-04-01 18:18:49 +0000107 dbmrPaint->setColor(newColor);
108 }
robertphillips@google.com73743552013-02-05 20:51:49 +0000109 }
robertphillips@google.com50c84da2013-04-01 18:18:49 +0000110
111 canvas->deleteDrawCommandAt(curCommand+2); // restore
112 canvas->deleteDrawCommandAt(curCommand); // saveLayer
robertphillips@google.com73743552013-02-05 20:51:49 +0000113}
114
115// Check for:
116// SAVE_LAYER
117// SAVE
118// CLIP_RECT
119// DRAW_BITMAP_RECT_TO_RECT
120// RESTORE
121// RESTORE
122// where the saveLayer's color can be moved into the drawBitmapRect
robertphillips@google.com50c84da2013-04-01 18:18:49 +0000123static bool check_1(SkDebugCanvas* canvas, int curCommand) {
robertphillips9bafc302015-02-13 11:13:00 -0800124 if (SkDrawCommand::kSaveLayer_OpType != canvas->getDrawCommandAt(curCommand)->getType() ||
robertphillips@google.com50c84da2013-04-01 18:18:49 +0000125 canvas->getSize() <= curCommand+5 ||
robertphillips9bafc302015-02-13 11:13:00 -0800126 SkDrawCommand::kSave_OpType != canvas->getDrawCommandAt(curCommand+1)->getType() ||
127 SkDrawCommand::kClipRect_OpType != canvas->getDrawCommandAt(curCommand+2)->getType() ||
128 SkDrawCommand::kDrawBitmapRect_OpType != canvas->getDrawCommandAt(curCommand+3)->getType() ||
129 SkDrawCommand::kRestore_OpType != canvas->getDrawCommandAt(curCommand+4)->getType() ||
130 SkDrawCommand::kRestore_OpType != canvas->getDrawCommandAt(curCommand+5)->getType()) {
robertphillips@google.com73743552013-02-05 20:51:49 +0000131 return false;
robertphillips@google.com50c84da2013-04-01 18:18:49 +0000132 }
robertphillips@google.com73743552013-02-05 20:51:49 +0000133
commit-bot@chromium.org7a115912013-06-18 20:20:55 +0000134 SkSaveLayerCommand* saveLayer =
135 (SkSaveLayerCommand*) canvas->getDrawCommandAt(curCommand);
136 SkDrawBitmapRectCommand* dbmr =
137 (SkDrawBitmapRectCommand*) canvas->getDrawCommandAt(curCommand+3);
robertphillips@google.com73743552013-02-05 20:51:49 +0000138
139 const SkPaint* saveLayerPaint = saveLayer->paint();
140 SkPaint* dbmrPaint = dbmr->paint();
141
skia.committer@gmail.com3d18d062013-02-14 07:01:34 +0000142 // For this optimization we only fold the saveLayer and drawBitmapRect
robertphillips@google.com1780a3c2013-02-13 13:27:44 +0000143 // together if the saveLayer's draw is simple (i.e., no fancy effects) and
144 // and the only difference in the colors is that the saveLayer's can have
145 // an alpha while the drawBitmapRect's is opaque.
146 // TODO: it should be possible to fold them together even if they both
147 // have different non-255 alphas but this is low priority since we have
148 // never seen that case
149 // If either operation lacks a paint then the collapse is trivial
150 SkColor layerColor = saveLayerPaint->getColor() | 0xFF000000; // force opaque
151
robertphillips@google.com73743552013-02-05 20:51:49 +0000152 return NULL == saveLayerPaint ||
153 NULL == dbmrPaint ||
robertphillips@google.com1780a3c2013-02-13 13:27:44 +0000154 (is_simple(*saveLayerPaint) && dbmrPaint->getColor() == layerColor);
robertphillips@google.com73743552013-02-05 20:51:49 +0000155}
156
157// Fold the saveLayer's alpha into the drawBitmapRect and remove the saveLayer
158// and restore
robertphillips@google.com50c84da2013-04-01 18:18:49 +0000159static void apply_1(SkDebugCanvas* canvas, int curCommand) {
commit-bot@chromium.org7a115912013-06-18 20:20:55 +0000160 SkSaveLayerCommand* saveLayer =
161 (SkSaveLayerCommand*) canvas->getDrawCommandAt(curCommand);
robertphillips@google.com73743552013-02-05 20:51:49 +0000162 const SkPaint* saveLayerPaint = saveLayer->paint();
robertphillips@google.com73743552013-02-05 20:51:49 +0000163
robertphillips@google.com50c84da2013-04-01 18:18:49 +0000164 // if (NULL == saveLayerPaint) the dbmr's paint doesn't need to be changed
bsalomon49f085d2014-09-05 13:34:00 -0700165 if (saveLayerPaint) {
commit-bot@chromium.org7a115912013-06-18 20:20:55 +0000166 SkDrawBitmapRectCommand* dbmr =
167 (SkDrawBitmapRectCommand*) canvas->getDrawCommandAt(curCommand+3);
robertphillips@google.com50c84da2013-04-01 18:18:49 +0000168 SkPaint* dbmrPaint = dbmr->paint();
169
170 if (NULL == dbmrPaint) {
171 dbmr->setPaint(*saveLayerPaint);
172 } else {
173 SkColor newColor = SkColorSetA(dbmrPaint->getColor(),
174 SkColorGetA(saveLayerPaint->getColor()));
175 dbmrPaint->setColor(newColor);
176 }
robertphillips@google.com73743552013-02-05 20:51:49 +0000177 }
robertphillips@google.com50c84da2013-04-01 18:18:49 +0000178
179 canvas->deleteDrawCommandAt(curCommand+5); // restore
180 canvas->deleteDrawCommandAt(curCommand); // saveLayer
robertphillips@google.com73743552013-02-05 20:51:49 +0000181}
182
robertphillips@google.comfebc0ec2013-03-11 22:53:11 +0000183// Check for:
184// SAVE
185// CLIP_RECT
186// DRAW_RECT
187// RESTORE
188// where the rect is entirely within the clip and the clip is an intersect
robertphillips@google.com50c84da2013-04-01 18:18:49 +0000189static bool check_2(SkDebugCanvas* canvas, int curCommand) {
robertphillips9bafc302015-02-13 11:13:00 -0800190 if (SkDrawCommand::kSave_OpType != canvas->getDrawCommandAt(curCommand)->getType() ||
robertphillips@google.com50c84da2013-04-01 18:18:49 +0000191 canvas->getSize() <= curCommand+4 ||
robertphillips9bafc302015-02-13 11:13:00 -0800192 SkDrawCommand::kClipRect_OpType != canvas->getDrawCommandAt(curCommand+1)->getType() ||
193 SkDrawCommand::kDrawRect_OpType != canvas->getDrawCommandAt(curCommand+2)->getType() ||
194 SkDrawCommand::kRestore_OpType != canvas->getDrawCommandAt(curCommand+3)->getType()) {
robertphillips@google.comfebc0ec2013-03-11 22:53:11 +0000195 return false;
robertphillips@google.com50c84da2013-04-01 18:18:49 +0000196 }
robertphillips@google.comfebc0ec2013-03-11 22:53:11 +0000197
commit-bot@chromium.org7a115912013-06-18 20:20:55 +0000198 SkClipRectCommand* cr =
199 (SkClipRectCommand*) canvas->getDrawCommandAt(curCommand+1);
200 SkDrawRectCommand* dr =
201 (SkDrawRectCommand*) canvas->getDrawCommandAt(curCommand+2);
robertphillips@google.comfebc0ec2013-03-11 22:53:11 +0000202
203 if (SkRegion::kIntersect_Op != cr->op()) {
204 return false;
205 }
206
207 return cr->rect().contains(dr->rect());
208}
209
210// Remove everything but the drawRect
robertphillips@google.com50c84da2013-04-01 18:18:49 +0000211static void apply_2(SkDebugCanvas* canvas, int curCommand) {
212 canvas->deleteDrawCommandAt(curCommand+3); // restore
213 // drawRect
214 canvas->deleteDrawCommandAt(curCommand+1); // clipRect
215 canvas->deleteDrawCommandAt(curCommand); // save
robertphillips@google.comfebc0ec2013-03-11 22:53:11 +0000216}
217
218// Check for:
219// SAVE
220// CLIP_RRECT
221// DRAW_RECT
222// RESTORE
223// where the rect entirely encloses the clip
robertphillips@google.com50c84da2013-04-01 18:18:49 +0000224static bool check_3(SkDebugCanvas* canvas, int curCommand) {
robertphillips9bafc302015-02-13 11:13:00 -0800225 if (SkDrawCommand::kSave_OpType != canvas->getDrawCommandAt(curCommand)->getType() ||
robertphillips@google.com50c84da2013-04-01 18:18:49 +0000226 canvas->getSize() <= curCommand+4 ||
robertphillips9bafc302015-02-13 11:13:00 -0800227 SkDrawCommand::kClipRRect_OpType != canvas->getDrawCommandAt(curCommand+1)->getType() ||
228 SkDrawCommand::kDrawRect_OpType != canvas->getDrawCommandAt(curCommand+2)->getType() ||
229 SkDrawCommand::kRestore_OpType != canvas->getDrawCommandAt(curCommand+3)->getType()) {
robertphillips@google.comfebc0ec2013-03-11 22:53:11 +0000230 return false;
robertphillips@google.com50c84da2013-04-01 18:18:49 +0000231 }
robertphillips@google.comfebc0ec2013-03-11 22:53:11 +0000232
commit-bot@chromium.org7a115912013-06-18 20:20:55 +0000233 SkClipRRectCommand* crr =
234 (SkClipRRectCommand*) canvas->getDrawCommandAt(curCommand+1);
235 SkDrawRectCommand* dr =
236 (SkDrawRectCommand*) canvas->getDrawCommandAt(curCommand+2);
robertphillips@google.comfebc0ec2013-03-11 22:53:11 +0000237
238 if (SkRegion::kIntersect_Op != crr->op()) {
239 return false;
240 }
241
242 return dr->rect().contains(crr->rrect().rect());
243}
244
245// Replace everything with a drawRRect with the paint from the drawRect
246// and the AA settings from the clipRRect
robertphillips@google.com50c84da2013-04-01 18:18:49 +0000247static void apply_3(SkDebugCanvas* canvas, int curCommand) {
robertphillips@google.comfebc0ec2013-03-11 22:53:11 +0000248
robertphillips@google.com50c84da2013-04-01 18:18:49 +0000249 canvas->deleteDrawCommandAt(curCommand+3); // restore
250
commit-bot@chromium.org7a115912013-06-18 20:20:55 +0000251 SkClipRRectCommand* crr =
252 (SkClipRRectCommand*) canvas->getDrawCommandAt(curCommand+1);
253 SkDrawRectCommand* dr =
254 (SkDrawRectCommand*) canvas->getDrawCommandAt(curCommand+2);
robertphillips@google.comfebc0ec2013-03-11 22:53:11 +0000255
256 // TODO: could skip paint re-creation if the AA settings already match
robertphillips@google.com91217d02013-03-17 18:33:46 +0000257 SkPaint newPaint = dr->paint();
robertphillips@google.comfebc0ec2013-03-11 22:53:11 +0000258 newPaint.setAntiAlias(crr->doAA());
commit-bot@chromium.org7a115912013-06-18 20:20:55 +0000259 SkDrawRRectCommand* drr = new SkDrawRRectCommand(crr->rrect(), newPaint);
robertphillips@google.com50c84da2013-04-01 18:18:49 +0000260 canvas->setDrawCommandAt(curCommand+2, drr);
261
262 canvas->deleteDrawCommandAt(curCommand+1); // clipRRect
263 canvas->deleteDrawCommandAt(curCommand); // save
robertphillips@google.comfebc0ec2013-03-11 22:53:11 +0000264}
265
266// Check for:
267// SAVE
268// CLIP_RECT
269// DRAW_BITMAP_RECT_TO_RECT
270// RESTORE
271// where the rect and drawBitmapRect dst exactly match
robertphillips@google.com50c84da2013-04-01 18:18:49 +0000272static bool check_4(SkDebugCanvas* canvas, int curCommand) {
robertphillips9bafc302015-02-13 11:13:00 -0800273 if (SkDrawCommand::kSave_OpType != canvas->getDrawCommandAt(curCommand)->getType() ||
robertphillips@google.com50c84da2013-04-01 18:18:49 +0000274 canvas->getSize() <= curCommand+4 ||
robertphillips9bafc302015-02-13 11:13:00 -0800275 SkDrawCommand::kClipRect_OpType != canvas->getDrawCommandAt(curCommand+1)->getType() ||
276 SkDrawCommand::kDrawBitmapRect_OpType != canvas->getDrawCommandAt(curCommand+2)->getType() ||
277 SkDrawCommand::kRestore_OpType != canvas->getDrawCommandAt(curCommand+3)->getType()) {
robertphillips@google.comfebc0ec2013-03-11 22:53:11 +0000278 return false;
robertphillips@google.com50c84da2013-04-01 18:18:49 +0000279 }
robertphillips@google.comfebc0ec2013-03-11 22:53:11 +0000280
commit-bot@chromium.org7a115912013-06-18 20:20:55 +0000281 SkClipRectCommand* cr =
282 (SkClipRectCommand*) canvas->getDrawCommandAt(curCommand+1);
283 SkDrawBitmapRectCommand* dbmr =
284 (SkDrawBitmapRectCommand*) canvas->getDrawCommandAt(curCommand+2);
robertphillips@google.comfebc0ec2013-03-11 22:53:11 +0000285
286 if (SkRegion::kIntersect_Op != cr->op()) {
287 return false;
288 }
289
290 return dbmr->dstRect() == cr->rect();
291}
292
293// Remove everything but the drawBitmapRect
robertphillips@google.com50c84da2013-04-01 18:18:49 +0000294static void apply_4(SkDebugCanvas* canvas, int curCommand) {
295 canvas->deleteDrawCommandAt(curCommand+3); // restore
296 // drawBitmapRectToRect
297 canvas->deleteDrawCommandAt(curCommand+1); // clipRect
298 canvas->deleteDrawCommandAt(curCommand); // save
robertphillips@google.comfebc0ec2013-03-11 22:53:11 +0000299}
300
robertphillips@google.com9105ad02013-03-17 18:46:16 +0000301// Check for:
robertphillips@google.comc3410b82013-03-28 12:25:25 +0000302// SAVE
303// CLIP_RECT
304// SAVE_LAYER
305// SAVE
306// CLIP_RECT
307// SAVE_LAYER
308// SAVE
309// CLIP_RECT
310// DRAWBITMAPRECTTORECT
311// RESTORE
312// RESTORE
313// RESTORE
314// RESTORE
315// RESTORE
316// where:
317// all the clipRect's are BW, nested, intersections
318// the drawBitmapRectToRect is a 1-1 copy from src to dest
319// the last (smallest) clip rect is a subset of the drawBitmapRectToRect's dest rect
320// all the saveLayer's paints can be rolled into the drawBitmapRectToRect's paint
321// This pattern is used by Google spreadsheet when drawing the toolbar buttons
robertphillips@google.com50c84da2013-04-01 18:18:49 +0000322static bool check_7(SkDebugCanvas* canvas, int curCommand) {
robertphillips9bafc302015-02-13 11:13:00 -0800323 if (SkDrawCommand::kSave_OpType != canvas->getDrawCommandAt(curCommand)->getType() ||
robertphillips@google.com50c84da2013-04-01 18:18:49 +0000324 canvas->getSize() <= curCommand+13 ||
robertphillips9bafc302015-02-13 11:13:00 -0800325 SkDrawCommand::kClipRect_OpType != canvas->getDrawCommandAt(curCommand+1)->getType() ||
326 SkDrawCommand::kSaveLayer_OpType != canvas->getDrawCommandAt(curCommand+2)->getType() ||
327 SkDrawCommand::kSave_OpType != canvas->getDrawCommandAt(curCommand+3)->getType() ||
328 SkDrawCommand::kClipRect_OpType != canvas->getDrawCommandAt(curCommand+4)->getType() ||
329 SkDrawCommand::kSaveLayer_OpType != canvas->getDrawCommandAt(curCommand+5)->getType() ||
330 SkDrawCommand::kSave_OpType != canvas->getDrawCommandAt(curCommand+6)->getType() ||
331 SkDrawCommand::kClipRect_OpType != canvas->getDrawCommandAt(curCommand+7)->getType() ||
332 SkDrawCommand::kDrawBitmapRect_OpType != canvas->getDrawCommandAt(curCommand+8)->getType() ||
333 SkDrawCommand::kRestore_OpType != canvas->getDrawCommandAt(curCommand+9)->getType() ||
334 SkDrawCommand::kRestore_OpType != canvas->getDrawCommandAt(curCommand+10)->getType() ||
335 SkDrawCommand::kRestore_OpType != canvas->getDrawCommandAt(curCommand+11)->getType() ||
336 SkDrawCommand::kRestore_OpType != canvas->getDrawCommandAt(curCommand+12)->getType() ||
337 SkDrawCommand::kRestore_OpType != canvas->getDrawCommandAt(curCommand+13)->getType()) {
robertphillips@google.comc3410b82013-03-28 12:25:25 +0000338 return false;
robertphillips@google.com50c84da2013-04-01 18:18:49 +0000339 }
robertphillips@google.comc3410b82013-03-28 12:25:25 +0000340
commit-bot@chromium.org7a115912013-06-18 20:20:55 +0000341 SkClipRectCommand* clip0 =
342 (SkClipRectCommand*) canvas->getDrawCommandAt(curCommand+1);
343 SkSaveLayerCommand* saveLayer0 =
344 (SkSaveLayerCommand*) canvas->getDrawCommandAt(curCommand+2);
345 SkClipRectCommand* clip1 =
346 (SkClipRectCommand*) canvas->getDrawCommandAt(curCommand+4);
347 SkSaveLayerCommand* saveLayer1 =
348 (SkSaveLayerCommand*) canvas->getDrawCommandAt(curCommand+5);
349 SkClipRectCommand* clip2 =
350 (SkClipRectCommand*) canvas->getDrawCommandAt(curCommand+7);
351 SkDrawBitmapRectCommand* dbmr =
352 (SkDrawBitmapRectCommand*) canvas->getDrawCommandAt(curCommand+8);
robertphillips@google.comc3410b82013-03-28 12:25:25 +0000353
354 if (clip0->doAA() || clip1->doAA() || clip2->doAA()) {
355 return false;
356 }
357
358 if (SkRegion::kIntersect_Op != clip0->op() ||
359 SkRegion::kIntersect_Op != clip1->op() ||
360 SkRegion::kIntersect_Op != clip2->op()) {
361 return false;
362 }
363
skia.committer@gmail.com6acd09e2013-03-29 07:01:22 +0000364 if (!clip0->rect().contains(clip1->rect()) ||
robertphillips@google.comc3410b82013-03-28 12:25:25 +0000365 !clip1->rect().contains(clip2->rect())) {
366 return false;
367 }
368
369 // The src->dest mapping needs to be 1-to-1
370 if (NULL == dbmr->srcRect()) {
371 if (dbmr->bitmap().width() != dbmr->dstRect().width() ||
372 dbmr->bitmap().height() != dbmr->dstRect().height()) {
373 return false;
374 }
375 } else {
376 if (dbmr->srcRect()->width() != dbmr->dstRect().width() ||
377 dbmr->srcRect()->height() != dbmr->dstRect().height()) {
378 return false;
379 }
380 }
381
382 if (!dbmr->dstRect().contains(clip2->rect())) {
383 return false;
384 }
385
386 const SkPaint* saveLayerPaint0 = saveLayer0->paint();
387 const SkPaint* saveLayerPaint1 = saveLayer1->paint();
388
bsalomon49f085d2014-09-05 13:34:00 -0700389 if ((saveLayerPaint0 && !is_simple(*saveLayerPaint0)) ||
390 (saveLayerPaint1 && !is_simple(*saveLayerPaint1))) {
robertphillips@google.comc3410b82013-03-28 12:25:25 +0000391 return false;
392 }
393
394 SkPaint* dbmrPaint = dbmr->paint();
395
396 if (NULL == dbmrPaint) {
skia.committer@gmail.com6acd09e2013-03-29 07:01:22 +0000397 return true;
robertphillips@google.comc3410b82013-03-28 12:25:25 +0000398 }
skia.committer@gmail.com6acd09e2013-03-29 07:01:22 +0000399
bsalomon49f085d2014-09-05 13:34:00 -0700400 if (saveLayerPaint0) {
robertphillips@google.comc3410b82013-03-28 12:25:25 +0000401 SkColor layerColor0 = saveLayerPaint0->getColor() | 0xFF000000; // force opaque
402 if (dbmrPaint->getColor() != layerColor0) {
403 return false;
404 }
405 }
406
bsalomon49f085d2014-09-05 13:34:00 -0700407 if (saveLayerPaint1) {
robertphillips@google.comc3410b82013-03-28 12:25:25 +0000408 SkColor layerColor1 = saveLayerPaint1->getColor() | 0xFF000000; // force opaque
409 if (dbmrPaint->getColor() != layerColor1) {
410 return false;
411 }
412 }
413
414 return true;
415}
416
417// Reduce to a single drawBitmapRectToRect call by folding the clipRect's into
418// the src and dst Rects and the saveLayer paints into the drawBitmapRectToRect's
419// paint.
robertphillips@google.com50c84da2013-04-01 18:18:49 +0000420static void apply_7(SkDebugCanvas* canvas, int curCommand) {
commit-bot@chromium.org7a115912013-06-18 20:20:55 +0000421 SkSaveLayerCommand* saveLayer0 =
422 (SkSaveLayerCommand*) canvas->getDrawCommandAt(curCommand+2);
423 SkSaveLayerCommand* saveLayer1 =
424 (SkSaveLayerCommand*) canvas->getDrawCommandAt(curCommand+5);
425 SkClipRectCommand* clip2 =
426 (SkClipRectCommand*) canvas->getDrawCommandAt(curCommand+7);
427 SkDrawBitmapRectCommand* dbmr =
428 (SkDrawBitmapRectCommand*) canvas->getDrawCommandAt(curCommand+8);
robertphillips@google.comc3410b82013-03-28 12:25:25 +0000429
430 SkScalar newSrcLeft = dbmr->srcRect()->fLeft + clip2->rect().fLeft - dbmr->dstRect().fLeft;
431 SkScalar newSrcTop = dbmr->srcRect()->fTop + clip2->rect().fTop - dbmr->dstRect().fTop;
432
skia.committer@gmail.com6acd09e2013-03-29 07:01:22 +0000433 SkRect newSrc = SkRect::MakeXYWH(newSrcLeft, newSrcTop,
robertphillips@google.comc3410b82013-03-28 12:25:25 +0000434 clip2->rect().width(), clip2->rect().height());
435
436 dbmr->setSrcRect(newSrc);
437 dbmr->setDstRect(clip2->rect());
438
439 SkColor color = 0xFF000000;
440 int a0, a1;
441
442 const SkPaint* saveLayerPaint0 = saveLayer0->paint();
bsalomon49f085d2014-09-05 13:34:00 -0700443 if (saveLayerPaint0) {
robertphillips@google.comc3410b82013-03-28 12:25:25 +0000444 color = saveLayerPaint0->getColor();
445 a0 = SkColorGetA(color);
446 } else {
447 a0 = 0xFF;
448 }
449
450 const SkPaint* saveLayerPaint1 = saveLayer1->paint();
bsalomon49f085d2014-09-05 13:34:00 -0700451 if (saveLayerPaint1) {
robertphillips@google.comc3410b82013-03-28 12:25:25 +0000452 color = saveLayerPaint1->getColor();
453 a1 = SkColorGetA(color);
454 } else {
455 a1 = 0xFF;
456 }
457
robertphillips@google.comc5257042013-04-02 15:30:03 +0000458 int newA = SkMulDiv255Round(a0, a1);
robertphillips@google.comc3410b82013-03-28 12:25:25 +0000459 SkASSERT(newA <= 0xFF);
460
461 SkPaint* dbmrPaint = dbmr->paint();
462
bsalomon49f085d2014-09-05 13:34:00 -0700463 if (dbmrPaint) {
robertphillips@google.comc3410b82013-03-28 12:25:25 +0000464 SkColor newColor = SkColorSetA(dbmrPaint->getColor(), newA);
465 dbmrPaint->setColor(newColor);
466 } else {
467 SkColor newColor = SkColorSetA(color, newA);
468
469 SkPaint newPaint;
470 newPaint.setColor(newColor);
471 dbmr->setPaint(newPaint);
472 }
473
474 // remove everything except the drawbitmaprect
robertphillips@google.com50c84da2013-04-01 18:18:49 +0000475 canvas->deleteDrawCommandAt(curCommand+13); // restore
476 canvas->deleteDrawCommandAt(curCommand+12); // restore
477 canvas->deleteDrawCommandAt(curCommand+11); // restore
478 canvas->deleteDrawCommandAt(curCommand+10); // restore
479 canvas->deleteDrawCommandAt(curCommand+9); // restore
480 canvas->deleteDrawCommandAt(curCommand+7); // clipRect
481 canvas->deleteDrawCommandAt(curCommand+6); // save
482 canvas->deleteDrawCommandAt(curCommand+5); // saveLayer
483 canvas->deleteDrawCommandAt(curCommand+4); // clipRect
484 canvas->deleteDrawCommandAt(curCommand+3); // save
485 canvas->deleteDrawCommandAt(curCommand+2); // saveLayer
486 canvas->deleteDrawCommandAt(curCommand+1); // clipRect
487 canvas->deleteDrawCommandAt(curCommand); // save
robertphillips@google.comc3410b82013-03-28 12:25:25 +0000488}
robertphillips@google.com9105ad02013-03-17 18:46:16 +0000489
commit-bot@chromium.org3bdf1642013-04-01 21:00:27 +0000490// Check for:
491// SAVE
492// CLIP_RECT
493// DRAWBITMAPRECTTORECT
494// RESTORE
495// where:
496// the drawBitmapRectToRect is a 1-1 copy from src to dest
497// the clip rect is BW and a subset of the drawBitmapRectToRect's dest rect
498static bool check_8(SkDebugCanvas* canvas, int curCommand) {
robertphillips9bafc302015-02-13 11:13:00 -0800499 if (SkDrawCommand::kSave_OpType != canvas->getDrawCommandAt(curCommand)->getType() ||
commit-bot@chromium.org3bdf1642013-04-01 21:00:27 +0000500 canvas->getSize() <= curCommand+4 ||
robertphillips9bafc302015-02-13 11:13:00 -0800501 SkDrawCommand::kClipRect_OpType != canvas->getDrawCommandAt(curCommand+1)->getType() ||
502 SkDrawCommand::kDrawBitmapRect_OpType != canvas->getDrawCommandAt(curCommand+2)->getType() ||
503 SkDrawCommand::kRestore_OpType != canvas->getDrawCommandAt(curCommand+3)->getType()) {
commit-bot@chromium.org3bdf1642013-04-01 21:00:27 +0000504 return false;
505 }
506
commit-bot@chromium.org7a115912013-06-18 20:20:55 +0000507 SkClipRectCommand* clip =
508 (SkClipRectCommand*) canvas->getDrawCommandAt(curCommand+1);
509 SkDrawBitmapRectCommand* dbmr =
510 (SkDrawBitmapRectCommand*) canvas->getDrawCommandAt(curCommand+2);
commit-bot@chromium.org3bdf1642013-04-01 21:00:27 +0000511
512 if (clip->doAA() || SkRegion::kIntersect_Op != clip->op()) {
513 return false;
514 }
515
516 // The src->dest mapping needs to be 1-to-1
517 if (NULL == dbmr->srcRect()) {
518 if (dbmr->bitmap().width() != dbmr->dstRect().width() ||
519 dbmr->bitmap().height() != dbmr->dstRect().height()) {
520 return false;
521 }
522 } else {
523 if (dbmr->srcRect()->width() != dbmr->dstRect().width() ||
524 dbmr->srcRect()->height() != dbmr->dstRect().height()) {
525 return false;
526 }
527 }
528
529 if (!dbmr->dstRect().contains(clip->rect())) {
530 return false;
531 }
532
533 return true;
534}
535
536// Fold the clipRect into the drawBitmapRectToRect's src and dest rects
537static void apply_8(SkDebugCanvas* canvas, int curCommand) {
commit-bot@chromium.org7a115912013-06-18 20:20:55 +0000538 SkClipRectCommand* clip =
539 (SkClipRectCommand*) canvas->getDrawCommandAt(curCommand+1);
540 SkDrawBitmapRectCommand* dbmr =
541 (SkDrawBitmapRectCommand*) canvas->getDrawCommandAt(curCommand+2);
commit-bot@chromium.org3bdf1642013-04-01 21:00:27 +0000542
543 SkScalar newSrcLeft, newSrcTop;
544
bsalomon49f085d2014-09-05 13:34:00 -0700545 if (dbmr->srcRect()) {
commit-bot@chromium.org3bdf1642013-04-01 21:00:27 +0000546 newSrcLeft = dbmr->srcRect()->fLeft + clip->rect().fLeft - dbmr->dstRect().fLeft;
547 newSrcTop = dbmr->srcRect()->fTop + clip->rect().fTop - dbmr->dstRect().fTop;
548 } else {
549 newSrcLeft = clip->rect().fLeft - dbmr->dstRect().fLeft;
550 newSrcTop = clip->rect().fTop - dbmr->dstRect().fTop;
551 }
552
553 SkRect newSrc = SkRect::MakeXYWH(newSrcLeft, newSrcTop,
554 clip->rect().width(), clip->rect().height());
555
556 dbmr->setSrcRect(newSrc);
557 dbmr->setDstRect(clip->rect());
558
559 // remove everything except the drawbitmaprect
560 canvas->deleteDrawCommandAt(curCommand+3);
561 canvas->deleteDrawCommandAt(curCommand+1);
562 canvas->deleteDrawCommandAt(curCommand);
563}
564
565// Check for:
566// SAVE
567// CLIP_RECT
568// DRAWBITMAPRECTTORECT
569// RESTORE
570// where:
571// clipRect is BW and encloses the DBMR2R's dest rect
572static bool check_9(SkDebugCanvas* canvas, int curCommand) {
robertphillips9bafc302015-02-13 11:13:00 -0800573 if (SkDrawCommand::kSave_OpType != canvas->getDrawCommandAt(curCommand)->getType() ||
commit-bot@chromium.org3bdf1642013-04-01 21:00:27 +0000574 canvas->getSize() <= curCommand+4 ||
robertphillips9bafc302015-02-13 11:13:00 -0800575 SkDrawCommand::kClipRect_OpType != canvas->getDrawCommandAt(curCommand+1)->getType() ||
576 SkDrawCommand::kDrawBitmapRect_OpType != canvas->getDrawCommandAt(curCommand+2)->getType() ||
577 SkDrawCommand::kRestore_OpType != canvas->getDrawCommandAt(curCommand+3)->getType()) {
commit-bot@chromium.org3bdf1642013-04-01 21:00:27 +0000578 return false;
579 }
580
commit-bot@chromium.org7a115912013-06-18 20:20:55 +0000581 SkClipRectCommand* clip =
582 (SkClipRectCommand*) canvas->getDrawCommandAt(curCommand+1);
583 SkDrawBitmapRectCommand* dbmr =
584 (SkDrawBitmapRectCommand*) canvas->getDrawCommandAt(curCommand+2);
commit-bot@chromium.org3bdf1642013-04-01 21:00:27 +0000585
586 if (clip->doAA() || SkRegion::kIntersect_Op != clip->op()) {
587 return false;
588 }
589
590 if (!clip->rect().contains(dbmr->dstRect())) {
591 return false;
592 }
593
594 return true;
595}
596
597// remove everything except the drawbitmaprect
598static void apply_9(SkDebugCanvas* canvas, int curCommand) {
599 canvas->deleteDrawCommandAt(curCommand+3); // restore
600 // drawBitmapRectToRect
601 canvas->deleteDrawCommandAt(curCommand+1); // clipRect
602 canvas->deleteDrawCommandAt(curCommand); // save
603}
604
robertphillips@google.com50c84da2013-04-01 18:18:49 +0000605typedef bool (*PFCheck)(SkDebugCanvas* canvas, int curCommand);
606typedef void (*PFApply)(SkDebugCanvas* canvas, int curCommand);
robertphillips@google.com73743552013-02-05 20:51:49 +0000607
608struct OptTableEntry {
609 PFCheck fCheck;
610 PFApply fApply;
611 int fNumTimesApplied;
612} gOptTable[] = {
613 { check_0, apply_0, 0 },
614 { check_1, apply_1, 0 },
robertphillips@google.comfebc0ec2013-03-11 22:53:11 +0000615 { check_2, apply_2, 0 },
616 { check_3, apply_3, 0 },
617 { check_4, apply_4, 0 },
robertphillips@google.comc3410b82013-03-28 12:25:25 +0000618 { check_7, apply_7, 0 },
commit-bot@chromium.org3bdf1642013-04-01 21:00:27 +0000619 { check_8, apply_8, 0 },
620 { check_9, apply_9, 0 },
robertphillips@google.com73743552013-02-05 20:51:49 +0000621};
622
robertphillips@google.com50c84da2013-04-01 18:18:49 +0000623
robertphillips@google.com3b0a9fe2013-01-31 15:56:22 +0000624static int filter_picture(const SkString& inFile, const SkString& outFile) {
reed90d0ff02014-11-24 12:02:31 -0800625 SkAutoTUnref<SkPicture> inPicture;
djsollen@google.coma09e8832012-11-13 18:50:33 +0000626
627 SkFILEStream inStream(inFile.c_str());
628 if (inStream.isValid()) {
scroggo@google.comf1754ec2013-06-28 21:32:00 +0000629 inPicture.reset(SkPicture::CreateFromStream(&inStream));
djsollen@google.coma09e8832012-11-13 18:50:33 +0000630 }
631
robertphillips@google.com4d98b742013-05-10 14:51:54 +0000632 if (NULL == inPicture.get()) {
djsollen@google.coma09e8832012-11-13 18:50:33 +0000633 SkDebugf("Could not read file %s\n", inFile.c_str());
634 return -1;
635 }
636
robertphillips@google.com73743552013-02-05 20:51:49 +0000637 int localCount[SK_ARRAY_COUNT(gOptTable)];
638
639 memset(localCount, 0, sizeof(localCount));
640
robertphillipsa8d7f0b2014-08-29 08:03:56 -0700641 SkDebugCanvas debugCanvas(SkScalarCeilToInt(inPicture->cullRect().width()),
642 SkScalarCeilToInt(inPicture->cullRect().height()));
robertphillipsc5ba71d2014-09-04 08:42:50 -0700643 inPicture->playback(&debugCanvas);
djsollen@google.coma09e8832012-11-13 18:50:33 +0000644
robertphillips@google.com50c84da2013-04-01 18:18:49 +0000645 // delete the initial save and restore since replaying the commands will
robertphillips@google.com73743552013-02-05 20:51:49 +0000646 // re-add them
robertphillips@google.com50c84da2013-04-01 18:18:49 +0000647 if (debugCanvas.getSize() > 1) {
648 debugCanvas.deleteDrawCommandAt(0);
649 debugCanvas.deleteDrawCommandAt(debugCanvas.getSize()-1);
robertphillips@google.com73743552013-02-05 20:51:49 +0000650 }
651
robertphillips@google.comd9c18532013-04-01 19:10:21 +0000652 bool changed = true;
robertphillips@google.com2e87ba02013-04-08 15:45:30 +0000653 int numBefore = debugCanvas.getSize();
robertphillips@google.comd9c18532013-04-01 19:10:21 +0000654
655 while (changed) {
656 changed = false;
657 for (int i = 0; i < debugCanvas.getSize(); ++i) {
658 for (size_t opt = 0; opt < SK_ARRAY_COUNT(gOptTable); ++opt) {
659 if ((*gOptTable[opt].fCheck)(&debugCanvas, i)) {
660 (*gOptTable[opt].fApply)(&debugCanvas, i);
661
662 ++gOptTable[opt].fNumTimesApplied;
663 ++localCount[opt];
664
665 if (debugCanvas.getSize() == i) {
666 // the optimization removed all the remaining operations
667 break;
668 }
669
670 opt = 0; // try all the opts all over again
671 changed = true;
672 }
robertphillips@google.com3b0a9fe2013-01-31 15:56:22 +0000673 }
674 }
675 }
djsollen@google.coma09e8832012-11-13 18:50:33 +0000676
robertphillips@google.com2e87ba02013-04-08 15:45:30 +0000677 int numAfter = debugCanvas.getSize();
678
djsollen@google.coma09e8832012-11-13 18:50:33 +0000679 if (!outFile.isEmpty()) {
robertphillips@google.com84b18c72014-04-13 19:09:42 +0000680 SkPictureRecorder recorder;
robertphillipsa8d7f0b2014-08-29 08:03:56 -0700681 SkCanvas* canvas = recorder.beginRecording(inPicture->cullRect().width(),
682 inPicture->cullRect().height(),
683 NULL, 0);
robertphillips@google.com3b0a9fe2013-01-31 15:56:22 +0000684 debugCanvas.draw(canvas);
robertphillips@google.com84b18c72014-04-13 19:09:42 +0000685 SkAutoTUnref<SkPicture> outPicture(recorder.endRecording());
robertphillips@google.com3b0a9fe2013-01-31 15:56:22 +0000686
djsollen@google.coma09e8832012-11-13 18:50:33 +0000687 SkFILEWStream outStream(outFile.c_str());
688
robertphillips@google.com84b18c72014-04-13 19:09:42 +0000689 outPicture->serialize(&outStream);
djsollen@google.coma09e8832012-11-13 18:50:33 +0000690 }
691
robertphillips@google.com73743552013-02-05 20:51:49 +0000692 bool someOptFired = false;
693 for (size_t opt = 0; opt < SK_ARRAY_COUNT(gOptTable); ++opt) {
694 if (0 != localCount[opt]) {
695 SkDebugf("%d: %d ", opt, localCount[opt]);
696 someOptFired = true;
697 }
698 }
699
700 if (!someOptFired) {
701 SkDebugf("No opts fired\n");
702 } else {
skia.committer@gmail.com32840172013-04-09 07:01:27 +0000703 SkDebugf("\t before: %d after: %d delta: %d\n",
robertphillips@google.com2e87ba02013-04-08 15:45:30 +0000704 numBefore, numAfter, numBefore-numAfter);
robertphillips@google.com73743552013-02-05 20:51:49 +0000705 }
706
djsollen@google.coma09e8832012-11-13 18:50:33 +0000707 return 0;
708}
709
tfarina@chromium.orga5b7cc02012-10-08 14:41:10 +0000710// This function is not marked as 'static' so it can be referenced externally
711// in the iOS build.
humper@google.com05af1af2013-01-07 16:47:43 +0000712int tool_main(int argc, char** argv); // suppress a warning on mac
713
caryclark@google.com9598f422012-10-09 12:32:37 +0000714int tool_main(int argc, char** argv) {
robertphillips@google.com4d98b742013-05-10 14:51:54 +0000715#if SK_ENABLE_INST_COUNT
716 gPrintInstCount = true;
717#endif
718
robertphillips@google.comc7e4a5a2012-10-04 13:00:33 +0000719 SkGraphics::Init();
720
robertphillips@google.com801cee12012-10-19 19:06:11 +0000721 if (argc < 3) {
robertphillips@google.comc7e4a5a2012-10-04 13:00:33 +0000722 usage();
723 return -1;
724 }
725
robertphillips@google.com3b0a9fe2013-01-31 15:56:22 +0000726 SkString inFile, outFile, inDir, outDir;
robertphillips@google.com801cee12012-10-19 19:06:11 +0000727
robertphillips@google.comc7e4a5a2012-10-04 13:00:33 +0000728 char* const* stop = argv + argc;
729 for (++argv; argv < stop; ++argv) {
730 if (strcmp(*argv, "-i") == 0) {
731 argv++;
732 if (argv < stop && **argv) {
733 inFile.set(*argv);
734 } else {
robertphillips@google.com801cee12012-10-19 19:06:11 +0000735 SkDebugf("missing arg for -i\n");
robertphillips@google.comc7e4a5a2012-10-04 13:00:33 +0000736 usage();
737 return -1;
738 }
djsollen@google.coma09e8832012-11-13 18:50:33 +0000739 } else if (strcmp(*argv, "--input-dir") == 0) {
740 argv++;
741 if (argv < stop && **argv) {
742 inDir.set(*argv);
743 } else {
744 SkDebugf("missing arg for --input-dir\n");
745 usage();
746 return -1;
747 }
748 } else if (strcmp(*argv, "--output-dir") == 0) {
749 argv++;
750 if (argv < stop && **argv) {
751 outDir.set(*argv);
752 } else {
753 SkDebugf("missing arg for --output-dir\n");
754 usage();
755 return -1;
756 }
robertphillips@google.comc7e4a5a2012-10-04 13:00:33 +0000757 } else if (strcmp(*argv, "-o") == 0) {
758 argv++;
759 if (argv < stop && **argv) {
760 outFile.set(*argv);
761 } else {
robertphillips@google.com801cee12012-10-19 19:06:11 +0000762 SkDebugf("missing arg for -o\n");
763 usage();
764 return -1;
765 }
robertphillips@google.comc7e4a5a2012-10-04 13:00:33 +0000766 } else if (strcmp(*argv, "--help") == 0 || strcmp(*argv, "-h") == 0) {
767 usage();
768 return 0;
769 } else {
770 SkDebugf("unknown arg %s\n", *argv);
771 usage();
772 return -1;
773 }
774 }
775
djsollen@google.coma09e8832012-11-13 18:50:33 +0000776 SkOSFile::Iter iter(inDir.c_str(), "skp");
humper@google.com05af1af2013-01-07 16:47:43 +0000777
djsollen@google.coma09e8832012-11-13 18:50:33 +0000778 SkString inputFilename, outputFilename;
779 if (iter.next(&inputFilename)) {
robertphillips@google.comc7e4a5a2012-10-04 13:00:33 +0000780
djsollen@google.coma09e8832012-11-13 18:50:33 +0000781 do {
tfarinaa8e2e152014-07-28 19:26:58 -0700782 inFile = SkOSPath::Join(inDir.c_str(), inputFilename.c_str());
djsollen@google.coma09e8832012-11-13 18:50:33 +0000783 if (!outDir.isEmpty()) {
tfarinaa8e2e152014-07-28 19:26:58 -0700784 outFile = SkOSPath::Join(outDir.c_str(), inputFilename.c_str());
djsollen@google.coma09e8832012-11-13 18:50:33 +0000785 }
786 SkDebugf("Executing %s\n", inputFilename.c_str());
robertphillips@google.com3b0a9fe2013-01-31 15:56:22 +0000787 filter_picture(inFile, outFile);
djsollen@google.coma09e8832012-11-13 18:50:33 +0000788 } while(iter.next(&inputFilename));
robertphillips@google.comc7e4a5a2012-10-04 13:00:33 +0000789
djsollen@google.coma09e8832012-11-13 18:50:33 +0000790 } else if (!inFile.isEmpty()) {
robertphillips@google.com3b0a9fe2013-01-31 15:56:22 +0000791 filter_picture(inFile, outFile);
djsollen@google.coma09e8832012-11-13 18:50:33 +0000792 } else {
793 usage();
robertphillips@google.comc7e4a5a2012-10-04 13:00:33 +0000794 return -1;
795 }
796
robertphillips@google.com73743552013-02-05 20:51:49 +0000797 for (size_t opt = 0; opt < SK_ARRAY_COUNT(gOptTable); ++opt) {
798 SkDebugf("opt %d: %d\n", opt, gOptTable[opt].fNumTimesApplied);
799 }
800
robertphillips@google.comc7e4a5a2012-10-04 13:00:33 +0000801 SkGraphics::Term();
robertphillips@google.comc7e4a5a2012-10-04 13:00:33 +0000802 return 0;
803}
804
805#if !defined SK_BUILD_FOR_IOS
806int main(int argc, char * const argv[]) {
caryclark@google.com9598f422012-10-09 12:32:37 +0000807 return tool_main(argc, (char**) argv);
robertphillips@google.comc7e4a5a2012-10-04 13:00:33 +0000808}
809#endif