| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2012 Google Inc. | 2 * Copyright 2012 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "SkDebugCanvas.h" | 8 #include "SkDebugCanvas.h" |
| 9 #include "SkDevice.h" | 9 #include "SkDevice.h" |
| 10 #include "SkGraphics.h" | 10 #include "SkGraphics.h" |
| (...skipping 22 matching lines...) Expand all Loading... |
| 33 return NULL == p.getPathEffect() && | 33 return NULL == p.getPathEffect() && |
| 34 NULL == p.getShader() && | 34 NULL == p.getShader() && |
| 35 NULL == p.getXfermode() && | 35 NULL == p.getXfermode() && |
| 36 NULL == p.getMaskFilter() && | 36 NULL == p.getMaskFilter() && |
| 37 NULL == p.getColorFilter() && | 37 NULL == p.getColorFilter() && |
| 38 NULL == p.getRasterizer() && | 38 NULL == p.getRasterizer() && |
| 39 NULL == p.getLooper() && | 39 NULL == p.getLooper() && |
| 40 NULL == p.getImageFilter(); | 40 NULL == p.getImageFilter(); |
| 41 } | 41 } |
| 42 | 42 |
| 43 |
| 43 // Check for: | 44 // Check for: |
| 44 // SAVE_LAYER | 45 // SAVE_LAYER |
| 45 // DRAW_BITMAP_RECT_TO_RECT | 46 // DRAW_BITMAP_RECT_TO_RECT |
| 46 // RESTORE | 47 // RESTORE |
| 47 // where the saveLayer's color can be moved into the drawBitmapRect | 48 // where the saveLayer's color can be moved into the drawBitmapRect |
| 48 static bool check_0(const SkTDArray<SkDrawCommand*>& commands, int curCommand) { | 49 static bool check_0(SkDebugCanvas* canvas, int curCommand) { |
| 49 if (SAVE_LAYER != commands[curCommand]->getType() || | 50 if (SAVE_LAYER != canvas->getDrawCommandAt(curCommand)->getType() || |
| 50 commands.count() <= curCommand+2 || | 51 canvas->getSize() <= curCommand+2 || |
| 51 DRAW_BITMAP_RECT_TO_RECT != commands[curCommand+1]->getType() || | 52 DRAW_BITMAP_RECT_TO_RECT != canvas->getDrawCommandAt(curCommand+1)->getT
ype() || |
| 52 RESTORE != commands[curCommand+2]->getType()) | 53 RESTORE != canvas->getDrawCommandAt(curCommand+2)->getType()) { |
| 53 return false; | 54 return false; |
| 55 } |
| 54 | 56 |
| 55 SaveLayer* saveLayer = (SaveLayer*) commands[curCommand]; | 57 SaveLayer* saveLayer = (SaveLayer*) canvas->getDrawCommandAt(curCommand); |
| 56 DrawBitmapRect* dbmr = (DrawBitmapRect*) commands[curCommand+1]; | 58 DrawBitmapRect* dbmr = (DrawBitmapRect*) canvas->getDrawCommandAt(curCommand
+1); |
| 57 | 59 |
| 58 const SkPaint* saveLayerPaint = saveLayer->paint(); | 60 const SkPaint* saveLayerPaint = saveLayer->paint(); |
| 59 SkPaint* dbmrPaint = dbmr->paint(); | 61 SkPaint* dbmrPaint = dbmr->paint(); |
| 60 | 62 |
| 61 // For this optimization we only fold the saveLayer and drawBitmapRect | 63 // For this optimization we only fold the saveLayer and drawBitmapRect |
| 62 // together if the saveLayer's draw is simple (i.e., no fancy effects) and | 64 // together if the saveLayer's draw is simple (i.e., no fancy effects) and |
| 63 // and the only difference in the colors is that the saveLayer's can have | 65 // and the only difference in the colors is that the saveLayer's can have |
| 64 // an alpha while the drawBitmapRect's is opaque. | 66 // an alpha while the drawBitmapRect's is opaque. |
| 65 // TODO: it should be possible to fold them together even if they both | 67 // TODO: it should be possible to fold them together even if they both |
| 66 // have different non-255 alphas but this is low priority since we have | 68 // have different non-255 alphas but this is low priority since we have |
| 67 // never seen that case | 69 // never seen that case |
| 68 // If either operation lacks a paint then the collapse is trivial | 70 // If either operation lacks a paint then the collapse is trivial |
| 69 SkColor layerColor = saveLayerPaint->getColor() | 0xFF000000; // force opaqu
e | 71 SkColor layerColor = saveLayerPaint->getColor() | 0xFF000000; // force opaqu
e |
| 70 | 72 |
| 71 return NULL == saveLayerPaint || | 73 return NULL == saveLayerPaint || |
| 72 NULL == dbmrPaint || | 74 NULL == dbmrPaint || |
| 73 (is_simple(*saveLayerPaint) && dbmrPaint->getColor() == layerColor); | 75 (is_simple(*saveLayerPaint) && dbmrPaint->getColor() == layerColor); |
| 74 } | 76 } |
| 75 | 77 |
| 76 // Fold the saveLayer's alpha into the drawBitmapRect and remove the saveLayer | 78 // Fold the saveLayer's alpha into the drawBitmapRect and remove the saveLayer |
| 77 // and restore | 79 // and restore |
| 78 static void apply_0(SkTDArray<SkDrawCommand*>& commands, int curCommand) { | 80 static void apply_0(SkDebugCanvas* canvas, int curCommand) { |
| 79 SaveLayer* saveLayer = (SaveLayer*) commands[curCommand]; | 81 SaveLayer* saveLayer = (SaveLayer*) canvas->getDrawCommandAt(curCommand); |
| 80 DrawBitmapRect* dbmr = (DrawBitmapRect*) commands[curCommand+1]; | 82 const SkPaint* saveLayerPaint = saveLayer->paint(); |
| 81 Restore* restore = (Restore*) commands[curCommand+2]; | |
| 82 | 83 |
| 83 const SkPaint* saveLayerPaint = saveLayer->paint(); | 84 // if (NULL == saveLayerPaint) the dbmr's paint doesn't need to be changed |
| 84 SkPaint* dbmrPaint = dbmr->paint(); | 85 if (NULL != saveLayerPaint) { |
| 86 DrawBitmapRect* dbmr = (DrawBitmapRect*) canvas->getDrawCommandAt(curCom
mand+1); |
| 87 SkPaint* dbmrPaint = dbmr->paint(); |
| 85 | 88 |
| 86 if (NULL == saveLayerPaint) { | 89 if (NULL == dbmrPaint) { |
| 87 saveLayer->setVisible(false); | 90 // if the DBMR doesn't have a paint just use the saveLayer's |
| 88 restore->setVisible(false); | 91 dbmr->setPaint(*saveLayerPaint); |
| 89 } else if (NULL == dbmrPaint) { | 92 } else if (NULL != saveLayerPaint) { |
| 90 saveLayer->setVisible(false); | 93 SkColor newColor = SkColorSetA(dbmrPaint->getColor(), |
| 91 dbmr->setPaint(*saveLayerPaint); | 94 SkColorGetA(saveLayerPaint->getColor(
))); |
| 92 restore->setVisible(false); | 95 dbmrPaint->setColor(newColor); |
| 93 } else { | 96 } |
| 94 saveLayer->setVisible(false); | |
| 95 SkColor newColor = SkColorSetA(dbmrPaint->getColor(), | |
| 96 SkColorGetA(saveLayerPaint->getColor())); | |
| 97 dbmrPaint->setColor(newColor); | |
| 98 restore->setVisible(false); | |
| 99 } | 97 } |
| 98 |
| 99 canvas->deleteDrawCommandAt(curCommand+2); // restore |
| 100 canvas->deleteDrawCommandAt(curCommand); // saveLayer |
| 100 } | 101 } |
| 101 | 102 |
| 102 // Check for: | 103 // Check for: |
| 103 // SAVE_LAYER | 104 // SAVE_LAYER |
| 104 // SAVE | 105 // SAVE |
| 105 // CLIP_RECT | 106 // CLIP_RECT |
| 106 // DRAW_BITMAP_RECT_TO_RECT | 107 // DRAW_BITMAP_RECT_TO_RECT |
| 107 // RESTORE | 108 // RESTORE |
| 108 // RESTORE | 109 // RESTORE |
| 109 // where the saveLayer's color can be moved into the drawBitmapRect | 110 // where the saveLayer's color can be moved into the drawBitmapRect |
| 110 static bool check_1(const SkTDArray<SkDrawCommand*>& commands, int curCommand) { | 111 static bool check_1(SkDebugCanvas* canvas, int curCommand) { |
| 111 if (SAVE_LAYER != commands[curCommand]->getType() || | 112 if (SAVE_LAYER != canvas->getDrawCommandAt(curCommand)->getType() || |
| 112 commands.count() <= curCommand+5 || | 113 canvas->getSize() <= curCommand+5 || |
| 113 SAVE != commands[curCommand+1]->getType() || | 114 SAVE != canvas->getDrawCommandAt(curCommand+1)->getType() || |
| 114 CLIP_RECT != commands[curCommand+2]->getType() || | 115 CLIP_RECT != canvas->getDrawCommandAt(curCommand+2)->getType() || |
| 115 DRAW_BITMAP_RECT_TO_RECT != commands[curCommand+3]->getType() || | 116 DRAW_BITMAP_RECT_TO_RECT != canvas->getDrawCommandAt(curCommand+3)->getT
ype() || |
| 116 RESTORE != commands[curCommand+4]->getType() || | 117 RESTORE != canvas->getDrawCommandAt(curCommand+4)->getType() || |
| 117 RESTORE != commands[curCommand+5]->getType()) | 118 RESTORE != canvas->getDrawCommandAt(curCommand+5)->getType()) { |
| 118 return false; | 119 return false; |
| 120 } |
| 119 | 121 |
| 120 SaveLayer* saveLayer = (SaveLayer*) commands[curCommand]; | 122 SaveLayer* saveLayer = (SaveLayer*) canvas->getDrawCommandAt(curCommand); |
| 121 DrawBitmapRect* dbmr = (DrawBitmapRect*) commands[curCommand+3]; | 123 DrawBitmapRect* dbmr = (DrawBitmapRect*) canvas->getDrawCommandAt(curCommand
+3); |
| 122 | 124 |
| 123 const SkPaint* saveLayerPaint = saveLayer->paint(); | 125 const SkPaint* saveLayerPaint = saveLayer->paint(); |
| 124 SkPaint* dbmrPaint = dbmr->paint(); | 126 SkPaint* dbmrPaint = dbmr->paint(); |
| 125 | 127 |
| 126 // For this optimization we only fold the saveLayer and drawBitmapRect | 128 // For this optimization we only fold the saveLayer and drawBitmapRect |
| 127 // together if the saveLayer's draw is simple (i.e., no fancy effects) and | 129 // together if the saveLayer's draw is simple (i.e., no fancy effects) and |
| 128 // and the only difference in the colors is that the saveLayer's can have | 130 // and the only difference in the colors is that the saveLayer's can have |
| 129 // an alpha while the drawBitmapRect's is opaque. | 131 // an alpha while the drawBitmapRect's is opaque. |
| 130 // TODO: it should be possible to fold them together even if they both | 132 // TODO: it should be possible to fold them together even if they both |
| 131 // have different non-255 alphas but this is low priority since we have | 133 // have different non-255 alphas but this is low priority since we have |
| 132 // never seen that case | 134 // never seen that case |
| 133 // If either operation lacks a paint then the collapse is trivial | 135 // If either operation lacks a paint then the collapse is trivial |
| 134 SkColor layerColor = saveLayerPaint->getColor() | 0xFF000000; // force opaqu
e | 136 SkColor layerColor = saveLayerPaint->getColor() | 0xFF000000; // force opaqu
e |
| 135 | 137 |
| 136 return NULL == saveLayerPaint || | 138 return NULL == saveLayerPaint || |
| 137 NULL == dbmrPaint || | 139 NULL == dbmrPaint || |
| 138 (is_simple(*saveLayerPaint) && dbmrPaint->getColor() == layerColor); | 140 (is_simple(*saveLayerPaint) && dbmrPaint->getColor() == layerColor); |
| 139 } | 141 } |
| 140 | 142 |
| 141 // Fold the saveLayer's alpha into the drawBitmapRect and remove the saveLayer | 143 // Fold the saveLayer's alpha into the drawBitmapRect and remove the saveLayer |
| 142 // and restore | 144 // and restore |
| 143 static void apply_1(SkTDArray<SkDrawCommand*>& commands, int curCommand) { | 145 static void apply_1(SkDebugCanvas* canvas, int curCommand) { |
| 144 SaveLayer* saveLayer = (SaveLayer*) commands[curCommand]; | 146 SaveLayer* saveLayer = (SaveLayer*) canvas->getDrawCommandAt(curCommand); |
| 145 DrawBitmapRect* dbmr = (DrawBitmapRect*) commands[curCommand+3]; | 147 const SkPaint* saveLayerPaint = saveLayer->paint(); |
| 146 Restore* restore = (Restore*) commands[curCommand+5]; | |
| 147 | 148 |
| 148 const SkPaint* saveLayerPaint = saveLayer->paint(); | 149 // if (NULL == saveLayerPaint) the dbmr's paint doesn't need to be changed |
| 149 SkPaint* dbmrPaint = dbmr->paint(); | 150 if (NULL != saveLayerPaint) { |
| 151 DrawBitmapRect* dbmr = (DrawBitmapRect*) canvas->getDrawCommandAt(curCom
mand+3); |
| 152 SkPaint* dbmrPaint = dbmr->paint(); |
| 150 | 153 |
| 151 if (NULL == saveLayerPaint) { | 154 if (NULL == dbmrPaint) { |
| 152 saveLayer->setVisible(false); | 155 dbmr->setPaint(*saveLayerPaint); |
| 153 restore->setVisible(false); | 156 } else { |
| 154 } else if (NULL == dbmrPaint) { | 157 SkColor newColor = SkColorSetA(dbmrPaint->getColor(), |
| 155 saveLayer->setVisible(false); | 158 SkColorGetA(saveLayerPaint->getColor(
))); |
| 156 dbmr->setPaint(*saveLayerPaint); | 159 dbmrPaint->setColor(newColor); |
| 157 restore->setVisible(false); | 160 } |
| 158 } else { | |
| 159 saveLayer->setVisible(false); | |
| 160 SkColor newColor = SkColorSetA(dbmrPaint->getColor(), | |
| 161 SkColorGetA(saveLayerPaint->getColor())); | |
| 162 dbmrPaint->setColor(newColor); | |
| 163 restore->setVisible(false); | |
| 164 } | 161 } |
| 162 |
| 163 canvas->deleteDrawCommandAt(curCommand+5); // restore |
| 164 canvas->deleteDrawCommandAt(curCommand); // saveLayer |
| 165 } | 165 } |
| 166 | 166 |
| 167 // Check for: | 167 // Check for: |
| 168 // SAVE | 168 // SAVE |
| 169 // CLIP_RECT | 169 // CLIP_RECT |
| 170 // DRAW_RECT | 170 // DRAW_RECT |
| 171 // RESTORE | 171 // RESTORE |
| 172 // where the rect is entirely within the clip and the clip is an intersect | 172 // where the rect is entirely within the clip and the clip is an intersect |
| 173 static bool check_2(const SkTDArray<SkDrawCommand*>& commands, int curCommand) { | 173 static bool check_2(SkDebugCanvas* canvas, int curCommand) { |
| 174 if (SAVE != commands[curCommand]->getType() || | 174 if (SAVE != canvas->getDrawCommandAt(curCommand)->getType() || |
| 175 commands.count() <= curCommand+4 || | 175 canvas->getSize() <= curCommand+4 || |
| 176 CLIP_RECT != commands[curCommand+1]->getType() || | 176 CLIP_RECT != canvas->getDrawCommandAt(curCommand+1)->getType() || |
| 177 DRAW_RECT != commands[curCommand+2]->getType() || | 177 DRAW_RECT != canvas->getDrawCommandAt(curCommand+2)->getType() || |
| 178 RESTORE != commands[curCommand+3]->getType()) | 178 RESTORE != canvas->getDrawCommandAt(curCommand+3)->getType()) { |
| 179 return false; | 179 return false; |
| 180 } |
| 180 | 181 |
| 181 ClipRect* cr = (ClipRect*) commands[curCommand+1]; | 182 ClipRect* cr = (ClipRect*) canvas->getDrawCommandAt(curCommand+1); |
| 182 DrawRectC* dr = (DrawRectC*) commands[curCommand+2]; | 183 DrawRectC* dr = (DrawRectC*) canvas->getDrawCommandAt(curCommand+2); |
| 183 | 184 |
| 184 if (SkRegion::kIntersect_Op != cr->op()) { | 185 if (SkRegion::kIntersect_Op != cr->op()) { |
| 185 return false; | 186 return false; |
| 186 } | 187 } |
| 187 | 188 |
| 188 return cr->rect().contains(dr->rect()); | 189 return cr->rect().contains(dr->rect()); |
| 189 } | 190 } |
| 190 | 191 |
| 191 // Remove everything but the drawRect | 192 // Remove everything but the drawRect |
| 192 static void apply_2(SkTDArray<SkDrawCommand*>& commands, int curCommand) { | 193 static void apply_2(SkDebugCanvas* canvas, int curCommand) { |
| 193 Save* save = (Save*) commands[curCommand]; | 194 canvas->deleteDrawCommandAt(curCommand+3); // restore |
| 194 ClipRect* cr = (ClipRect*) commands[curCommand+1]; | 195 // drawRect |
| 195 Restore* restore = (Restore*) commands[curCommand+3]; | 196 canvas->deleteDrawCommandAt(curCommand+1); // clipRect |
| 196 | 197 canvas->deleteDrawCommandAt(curCommand); // save |
| 197 save->setVisible(false); | |
| 198 cr->setVisible(false); | |
| 199 // leave the drawRect alone | |
| 200 restore->setVisible(false); | |
| 201 } | 198 } |
| 202 | 199 |
| 203 // Check for: | 200 // Check for: |
| 204 // SAVE | 201 // SAVE |
| 205 // CLIP_RRECT | 202 // CLIP_RRECT |
| 206 // DRAW_RECT | 203 // DRAW_RECT |
| 207 // RESTORE | 204 // RESTORE |
| 208 // where the rect entirely encloses the clip | 205 // where the rect entirely encloses the clip |
| 209 static bool check_3(const SkTDArray<SkDrawCommand*>& commands, int curCommand) { | 206 static bool check_3(SkDebugCanvas* canvas, int curCommand) { |
| 210 if (SAVE != commands[curCommand]->getType() || | 207 if (SAVE != canvas->getDrawCommandAt(curCommand)->getType() || |
| 211 commands.count() <= curCommand+4 || | 208 canvas->getSize() <= curCommand+4 || |
| 212 CLIP_RRECT != commands[curCommand+1]->getType() || | 209 CLIP_RRECT != canvas->getDrawCommandAt(curCommand+1)->getType() || |
| 213 DRAW_RECT != commands[curCommand+2]->getType() || | 210 DRAW_RECT != canvas->getDrawCommandAt(curCommand+2)->getType() || |
| 214 RESTORE != commands[curCommand+3]->getType()) | 211 RESTORE != canvas->getDrawCommandAt(curCommand+3)->getType()) { |
| 215 return false; | 212 return false; |
| 213 } |
| 216 | 214 |
| 217 ClipRRect* crr = (ClipRRect*) commands[curCommand+1]; | 215 ClipRRect* crr = (ClipRRect*) canvas->getDrawCommandAt(curCommand+1); |
| 218 DrawRectC* dr = (DrawRectC*) commands[curCommand+2]; | 216 DrawRectC* dr = (DrawRectC*) canvas->getDrawCommandAt(curCommand+2); |
| 219 | 217 |
| 220 if (SkRegion::kIntersect_Op != crr->op()) { | 218 if (SkRegion::kIntersect_Op != crr->op()) { |
| 221 return false; | 219 return false; |
| 222 } | 220 } |
| 223 | 221 |
| 224 return dr->rect().contains(crr->rrect().rect()); | 222 return dr->rect().contains(crr->rrect().rect()); |
| 225 } | 223 } |
| 226 | 224 |
| 227 // Replace everything with a drawRRect with the paint from the drawRect | 225 // Replace everything with a drawRRect with the paint from the drawRect |
| 228 // and the AA settings from the clipRRect | 226 // and the AA settings from the clipRRect |
| 229 static void apply_3(SkTDArray<SkDrawCommand*>& commands, int curCommand) { | 227 static void apply_3(SkDebugCanvas* canvas, int curCommand) { |
| 230 Save* save = (Save*) commands[curCommand]; | |
| 231 ClipRRect* crr = (ClipRRect*) commands[curCommand+1]; | |
| 232 DrawRectC* dr = (DrawRectC*) commands[curCommand+2]; | |
| 233 Restore* restore = (Restore*) commands[curCommand+3]; | |
| 234 | 228 |
| 235 save->setVisible(false); | 229 canvas->deleteDrawCommandAt(curCommand+3); // restore |
| 236 crr->setVisible(false); | 230 |
| 237 dr->setVisible(false); | 231 ClipRRect* crr = (ClipRRect*) canvas->getDrawCommandAt(curCommand+1); |
| 238 restore->setVisible(false); | 232 DrawRectC* dr = (DrawRectC*) canvas->getDrawCommandAt(curCommand+2); |
| 239 | 233 |
| 240 // TODO: could skip paint re-creation if the AA settings already match | 234 // TODO: could skip paint re-creation if the AA settings already match |
| 241 SkPaint newPaint = dr->paint(); | 235 SkPaint newPaint = dr->paint(); |
| 242 newPaint.setAntiAlias(crr->doAA()); | 236 newPaint.setAntiAlias(crr->doAA()); |
| 243 DrawRRect* drr = new DrawRRect(crr->rrect(), newPaint); | 237 DrawRRect* drr = new DrawRRect(crr->rrect(), newPaint); |
| 244 commands[curCommand+2] = drr; | 238 canvas->setDrawCommandAt(curCommand+2, drr); |
| 239 |
| 240 canvas->deleteDrawCommandAt(curCommand+1); // clipRRect |
| 241 canvas->deleteDrawCommandAt(curCommand); // save |
| 245 } | 242 } |
| 246 | 243 |
| 247 // Check for: | 244 // Check for: |
| 248 // SAVE | 245 // SAVE |
| 249 // CLIP_RECT | 246 // CLIP_RECT |
| 250 // DRAW_BITMAP_RECT_TO_RECT | 247 // DRAW_BITMAP_RECT_TO_RECT |
| 251 // RESTORE | 248 // RESTORE |
| 252 // where the rect and drawBitmapRect dst exactly match | 249 // where the rect and drawBitmapRect dst exactly match |
| 253 static bool check_4(const SkTDArray<SkDrawCommand*>& commands, int curCommand) { | 250 static bool check_4(SkDebugCanvas* canvas, int curCommand) { |
| 254 if (SAVE != commands[curCommand]->getType() || | 251 if (SAVE != canvas->getDrawCommandAt(curCommand)->getType() || |
| 255 commands.count() <= curCommand+4 || | 252 canvas->getSize() <= curCommand+4 || |
| 256 CLIP_RECT != commands[curCommand+1]->getType() || | 253 CLIP_RECT != canvas->getDrawCommandAt(curCommand+1)->getType() || |
| 257 DRAW_BITMAP_RECT_TO_RECT != commands[curCommand+2]->getType() || | 254 DRAW_BITMAP_RECT_TO_RECT != canvas->getDrawCommandAt(curCommand+2)->getT
ype() || |
| 258 RESTORE != commands[curCommand+3]->getType()) | 255 RESTORE != canvas->getDrawCommandAt(curCommand+3)->getType()) { |
| 259 return false; | 256 return false; |
| 257 } |
| 260 | 258 |
| 261 ClipRect* cr = (ClipRect*) commands[curCommand+1]; | 259 ClipRect* cr = (ClipRect*) canvas->getDrawCommandAt(curCommand+1); |
| 262 DrawBitmapRect* dbmr = (DrawBitmapRect*) commands[curCommand+2]; | 260 DrawBitmapRect* dbmr = (DrawBitmapRect*) canvas->getDrawCommandAt(curComman
d+2); |
| 263 | 261 |
| 264 if (SkRegion::kIntersect_Op != cr->op()) { | 262 if (SkRegion::kIntersect_Op != cr->op()) { |
| 265 return false; | 263 return false; |
| 266 } | 264 } |
| 267 | 265 |
| 268 return dbmr->dstRect() == cr->rect(); | 266 return dbmr->dstRect() == cr->rect(); |
| 269 } | 267 } |
| 270 | 268 |
| 271 // Remove everything but the drawBitmapRect | 269 // Remove everything but the drawBitmapRect |
| 272 static void apply_4(SkTDArray<SkDrawCommand*>& commands, int curCommand) { | 270 static void apply_4(SkDebugCanvas* canvas, int curCommand) { |
| 273 Save* save = (Save*) commands[curCommand]; | 271 canvas->deleteDrawCommandAt(curCommand+3); // restore |
| 274 ClipRect* cr = (ClipRect*) commands[curCommand+1]; | 272 // drawBitmapRectToRect |
| 275 Restore* restore = (Restore*) commands[curCommand+3]; | 273 canvas->deleteDrawCommandAt(curCommand+1); // clipRect |
| 276 | 274 canvas->deleteDrawCommandAt(curCommand); // save |
| 277 save->setVisible(false); | |
| 278 cr->setVisible(false); | |
| 279 // leave drawBitmapRect alone | |
| 280 restore->setVisible(false); | |
| 281 } | 275 } |
| 282 | 276 |
| 283 // Check for: | 277 // Check for: |
| 284 // TRANSLATE | 278 // TRANSLATE |
| 285 // where the translate is zero | 279 // where the translate is zero |
| 286 static bool check_5(const SkTDArray<SkDrawCommand*>& commands, int curCommand) { | 280 static bool check_5(SkDebugCanvas* canvas, int curCommand) { |
| 287 if (TRANSLATE != commands[curCommand]->getType()) { | 281 if (TRANSLATE != canvas->getDrawCommandAt(curCommand)->getType()) { |
| 288 return false; | 282 return false; |
| 289 } | 283 } |
| 290 | 284 |
| 291 Translate* t = (Translate*) commands[curCommand]; | 285 Translate* t = (Translate*) canvas->getDrawCommandAt(curCommand); |
| 292 | 286 |
| 293 return 0 == t->x() && 0 == t->y(); | 287 return 0 == t->x() && 0 == t->y(); |
| 294 } | 288 } |
| 295 | 289 |
| 296 // Just remove the translate | 290 // Just remove the translate |
| 297 static void apply_5(SkTDArray<SkDrawCommand*>& commands, int curCommand) { | 291 static void apply_5(SkDebugCanvas* canvas, int curCommand) { |
| 298 Translate* t = (Translate*) commands[curCommand]; | 292 canvas->deleteDrawCommandAt(curCommand); // translate |
| 299 | |
| 300 t->setVisible(false); | |
| 301 } | 293 } |
| 302 | 294 |
| 303 // Check for: | 295 // Check for: |
| 304 // SCALE | 296 // SCALE |
| 305 // where the scale is 1,1 | 297 // where the scale is 1,1 |
| 306 static bool check_6(const SkTDArray<SkDrawCommand*>& commands, int curCommand) { | 298 static bool check_6(SkDebugCanvas* canvas, int curCommand) { |
| 307 if (SCALE != commands[curCommand]->getType()) { | 299 if (SCALE != canvas->getDrawCommandAt(curCommand)->getType()) { |
| 308 return false; | 300 return false; |
| 309 } | 301 } |
| 310 | 302 |
| 311 Scale* s = (Scale*) commands[curCommand]; | 303 Scale* s = (Scale*) canvas->getDrawCommandAt(curCommand); |
| 312 | 304 |
| 313 return SK_Scalar1 == s->x() && SK_Scalar1 == s->y(); | 305 return SK_Scalar1 == s->x() && SK_Scalar1 == s->y(); |
| 314 } | 306 } |
| 315 | 307 |
| 316 // Just remove the scale | 308 // Just remove the scale |
| 317 static void apply_6(SkTDArray<SkDrawCommand*>& commands, int curCommand) { | 309 static void apply_6(SkDebugCanvas* canvas, int curCommand) { |
| 318 Scale* s = (Scale*) commands[curCommand]; | 310 canvas->deleteDrawCommandAt(curCommand); // scale |
| 319 | |
| 320 s->setVisible(false); | |
| 321 } | 311 } |
| 322 | 312 |
| 323 // Check for: | 313 // Check for: |
| 324 // SAVE | 314 // SAVE |
| 325 // CLIP_RECT | 315 // CLIP_RECT |
| 326 // SAVE_LAYER | 316 // SAVE_LAYER |
| 327 // SAVE | 317 // SAVE |
| 328 // CLIP_RECT | 318 // CLIP_RECT |
| 329 // SAVE_LAYER | 319 // SAVE_LAYER |
| 330 // SAVE | 320 // SAVE |
| 331 // CLIP_RECT | 321 // CLIP_RECT |
| 332 // DRAWBITMAPRECTTORECT | 322 // DRAWBITMAPRECTTORECT |
| 333 // RESTORE | 323 // RESTORE |
| 334 // RESTORE | 324 // RESTORE |
| 335 // RESTORE | 325 // RESTORE |
| 336 // RESTORE | 326 // RESTORE |
| 337 // RESTORE | 327 // RESTORE |
| 338 // where: | 328 // where: |
| 339 // all the clipRect's are BW, nested, intersections | 329 // all the clipRect's are BW, nested, intersections |
| 340 // the drawBitmapRectToRect is a 1-1 copy from src to dest | 330 // the drawBitmapRectToRect is a 1-1 copy from src to dest |
| 341 // the last (smallest) clip rect is a subset of the drawBitmapRectToRect's
dest rect | 331 // the last (smallest) clip rect is a subset of the drawBitmapRectToRect's
dest rect |
| 342 // all the saveLayer's paints can be rolled into the drawBitmapRectToRect's
paint | 332 // all the saveLayer's paints can be rolled into the drawBitmapRectToRect's
paint |
| 343 // This pattern is used by Google spreadsheet when drawing the toolbar buttons | 333 // This pattern is used by Google spreadsheet when drawing the toolbar buttons |
| 344 static bool check_7(const SkTDArray<SkDrawCommand*>& commands, int curCommand) { | 334 static bool check_7(SkDebugCanvas* canvas, int curCommand) { |
| 345 if (SAVE != commands[curCommand]->getType() || | 335 if (SAVE != canvas->getDrawCommandAt(curCommand)->getType() || |
| 346 commands.count() <= curCommand+13 || | 336 canvas->getSize() <= curCommand+13 || |
| 347 CLIP_RECT != commands[curCommand+1]->getType() || | 337 CLIP_RECT != canvas->getDrawCommandAt(curCommand+1)->getType() || |
| 348 SAVE_LAYER != commands[curCommand+2]->getType() || | 338 SAVE_LAYER != canvas->getDrawCommandAt(curCommand+2)->getType() || |
| 349 SAVE != commands[curCommand+3]->getType() || | 339 SAVE != canvas->getDrawCommandAt(curCommand+3)->getType() || |
| 350 CLIP_RECT != commands[curCommand+4]->getType() || | 340 CLIP_RECT != canvas->getDrawCommandAt(curCommand+4)->getType() || |
| 351 SAVE_LAYER != commands[curCommand+5]->getType() || | 341 SAVE_LAYER != canvas->getDrawCommandAt(curCommand+5)->getType() || |
| 352 SAVE != commands[curCommand+6]->getType() || | 342 SAVE != canvas->getDrawCommandAt(curCommand+6)->getType() || |
| 353 CLIP_RECT != commands[curCommand+7]->getType() || | 343 CLIP_RECT != canvas->getDrawCommandAt(curCommand+7)->getType() || |
| 354 DRAW_BITMAP_RECT_TO_RECT != commands[curCommand+8]->getType() || | 344 DRAW_BITMAP_RECT_TO_RECT != canvas->getDrawCommandAt(curCommand+8)->getT
ype() || |
| 355 RESTORE != commands[curCommand+9]->getType() || | 345 RESTORE != canvas->getDrawCommandAt(curCommand+9)->getType() || |
| 356 RESTORE != commands[curCommand+10]->getType() || | 346 RESTORE != canvas->getDrawCommandAt(curCommand+10)->getType() || |
| 357 RESTORE != commands[curCommand+11]->getType() || | 347 RESTORE != canvas->getDrawCommandAt(curCommand+11)->getType() || |
| 358 RESTORE != commands[curCommand+12]->getType() || | 348 RESTORE != canvas->getDrawCommandAt(curCommand+12)->getType() || |
| 359 RESTORE != commands[curCommand+13]->getType()) | 349 RESTORE != canvas->getDrawCommandAt(curCommand+13)->getType()) { |
| 360 return false; | 350 return false; |
| 351 } |
| 361 | 352 |
| 362 ClipRect* clip0 = (ClipRect*) commands[curCommand+1]; | 353 ClipRect* clip0 = (ClipRect*) canvas->getDrawCommandAt(curCommand+1); |
| 363 SaveLayer* saveLayer0 = (SaveLayer*) commands[curCommand+2]; | 354 SaveLayer* saveLayer0 = (SaveLayer*) canvas->getDrawCommandAt(curCommand+2); |
| 364 ClipRect* clip1 = (ClipRect*) commands[curCommand+4]; | 355 ClipRect* clip1 = (ClipRect*) canvas->getDrawCommandAt(curCommand+4); |
| 365 SaveLayer* saveLayer1 = (SaveLayer*) commands[curCommand+5]; | 356 SaveLayer* saveLayer1 = (SaveLayer*) canvas->getDrawCommandAt(curCommand+5); |
| 366 ClipRect* clip2 = (ClipRect*) commands[curCommand+7]; | 357 ClipRect* clip2 = (ClipRect*) canvas->getDrawCommandAt(curCommand+7); |
| 367 DrawBitmapRect* dbmr = (DrawBitmapRect*) commands[curCommand+8]; | 358 DrawBitmapRect* dbmr = (DrawBitmapRect*) canvas->getDrawCommandAt(curCommand
+8); |
| 368 | 359 |
| 369 if (clip0->doAA() || clip1->doAA() || clip2->doAA()) { | 360 if (clip0->doAA() || clip1->doAA() || clip2->doAA()) { |
| 370 return false; | 361 return false; |
| 371 } | 362 } |
| 372 | 363 |
| 373 if (SkRegion::kIntersect_Op != clip0->op() || | 364 if (SkRegion::kIntersect_Op != clip0->op() || |
| 374 SkRegion::kIntersect_Op != clip1->op() || | 365 SkRegion::kIntersect_Op != clip1->op() || |
| 375 SkRegion::kIntersect_Op != clip2->op()) { | 366 SkRegion::kIntersect_Op != clip2->op()) { |
| 376 return false; | 367 return false; |
| 377 } | 368 } |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 425 return false; | 416 return false; |
| 426 } | 417 } |
| 427 } | 418 } |
| 428 | 419 |
| 429 return true; | 420 return true; |
| 430 } | 421 } |
| 431 | 422 |
| 432 // Reduce to a single drawBitmapRectToRect call by folding the clipRect's into | 423 // Reduce to a single drawBitmapRectToRect call by folding the clipRect's into |
| 433 // the src and dst Rects and the saveLayer paints into the drawBitmapRectToRect'
s | 424 // the src and dst Rects and the saveLayer paints into the drawBitmapRectToRect'
s |
| 434 // paint. | 425 // paint. |
| 435 static void apply_7(SkTDArray<SkDrawCommand*>& commands, int curCommand) { | 426 static void apply_7(SkDebugCanvas* canvas, int curCommand) { |
| 436 Save* save0 = (Save*) commands[curCommand]; | 427 SaveLayer* saveLayer0 = (SaveLayer*) canvas->getDrawCommandAt(curCommand+2); |
| 437 ClipRect* clip0 = (ClipRect*) commands[curCommand+1]; | 428 SaveLayer* saveLayer1 = (SaveLayer*) canvas->getDrawCommandAt(curCommand+5); |
| 438 SaveLayer* saveLayer0 = (SaveLayer*) commands[curCommand+2]; | 429 ClipRect* clip2 = (ClipRect*) canvas->getDrawCommandAt(curCommand+7); |
| 439 Save* save1 = (Save*) commands[curCommand+3]; | 430 DrawBitmapRect* dbmr = (DrawBitmapRect*) canvas->getDrawCommandAt(curCommand
+8); |
| 440 ClipRect* clip1 = (ClipRect*) commands[curCommand+4]; | |
| 441 SaveLayer* saveLayer1 = (SaveLayer*) commands[curCommand+5]; | |
| 442 Save* save2 = (Save*) commands[curCommand+6]; | |
| 443 ClipRect* clip2 = (ClipRect*) commands[curCommand+7]; | |
| 444 DrawBitmapRect* dbmr = (DrawBitmapRect*) commands[curCommand+8]; | |
| 445 Restore* restore0 = (Restore*) commands[curCommand+9]; | |
| 446 Restore* restore1 = (Restore*) commands[curCommand+10]; | |
| 447 Restore* restore2 = (Restore*) commands[curCommand+11]; | |
| 448 Restore* restore3 = (Restore*) commands[curCommand+12]; | |
| 449 Restore* restore4 = (Restore*) commands[curCommand+13]; | |
| 450 | 431 |
| 451 SkScalar newSrcLeft = dbmr->srcRect()->fLeft + clip2->rect().fLeft - dbmr->d
stRect().fLeft; | 432 SkScalar newSrcLeft = dbmr->srcRect()->fLeft + clip2->rect().fLeft - dbmr->d
stRect().fLeft; |
| 452 SkScalar newSrcTop = dbmr->srcRect()->fTop + clip2->rect().fTop - dbmr->dstR
ect().fTop; | 433 SkScalar newSrcTop = dbmr->srcRect()->fTop + clip2->rect().fTop - dbmr->dstR
ect().fTop; |
| 453 | 434 |
| 454 SkRect newSrc = SkRect::MakeXYWH(newSrcLeft, newSrcTop, | 435 SkRect newSrc = SkRect::MakeXYWH(newSrcLeft, newSrcTop, |
| 455 clip2->rect().width(), clip2->rect().height
()); | 436 clip2->rect().width(), clip2->rect().height
()); |
| 456 | 437 |
| 457 dbmr->setSrcRect(newSrc); | 438 dbmr->setSrcRect(newSrc); |
| 458 dbmr->setDstRect(clip2->rect()); | 439 dbmr->setDstRect(clip2->rect()); |
| 459 | 440 |
| (...skipping 26 matching lines...) Expand all Loading... |
| 486 dbmrPaint->setColor(newColor); | 467 dbmrPaint->setColor(newColor); |
| 487 } else { | 468 } else { |
| 488 SkColor newColor = SkColorSetA(color, newA); | 469 SkColor newColor = SkColorSetA(color, newA); |
| 489 | 470 |
| 490 SkPaint newPaint; | 471 SkPaint newPaint; |
| 491 newPaint.setColor(newColor); | 472 newPaint.setColor(newColor); |
| 492 dbmr->setPaint(newPaint); | 473 dbmr->setPaint(newPaint); |
| 493 } | 474 } |
| 494 | 475 |
| 495 // remove everything except the drawbitmaprect | 476 // remove everything except the drawbitmaprect |
| 496 save0->setVisible(false); | 477 canvas->deleteDrawCommandAt(curCommand+13); // restore |
| 497 clip0->setVisible(false); | 478 canvas->deleteDrawCommandAt(curCommand+12); // restore |
| 498 saveLayer0->setVisible(false); | 479 canvas->deleteDrawCommandAt(curCommand+11); // restore |
| 499 save1->setVisible(false); | 480 canvas->deleteDrawCommandAt(curCommand+10); // restore |
| 500 clip1->setVisible(false); | 481 canvas->deleteDrawCommandAt(curCommand+9); // restore |
| 501 saveLayer1->setVisible(false); | 482 canvas->deleteDrawCommandAt(curCommand+7); // clipRect |
| 502 save2->setVisible(false); | 483 canvas->deleteDrawCommandAt(curCommand+6); // save |
| 503 clip2->setVisible(false); | 484 canvas->deleteDrawCommandAt(curCommand+5); // saveLayer |
| 504 restore0->setVisible(false); | 485 canvas->deleteDrawCommandAt(curCommand+4); // clipRect |
| 505 restore1->setVisible(false); | 486 canvas->deleteDrawCommandAt(curCommand+3); // save |
| 506 restore2->setVisible(false); | 487 canvas->deleteDrawCommandAt(curCommand+2); // saveLayer |
| 507 restore3->setVisible(false); | 488 canvas->deleteDrawCommandAt(curCommand+1); // clipRect |
| 508 restore4->setVisible(false); | 489 canvas->deleteDrawCommandAt(curCommand); // save |
| 509 } | 490 } |
| 510 | 491 |
| 511 typedef bool (*PFCheck)(const SkTDArray<SkDrawCommand*>& commands, int curComman
d); | 492 typedef bool (*PFCheck)(SkDebugCanvas* canvas, int curCommand); |
| 512 typedef void (*PFApply)(SkTDArray<SkDrawCommand*>& commands, int curCommand); | 493 typedef void (*PFApply)(SkDebugCanvas* canvas, int curCommand); |
| 513 | 494 |
| 514 struct OptTableEntry { | 495 struct OptTableEntry { |
| 515 PFCheck fCheck; | 496 PFCheck fCheck; |
| 516 PFApply fApply; | 497 PFApply fApply; |
| 517 int fNumTimesApplied; | 498 int fNumTimesApplied; |
| 518 } gOptTable[] = { | 499 } gOptTable[] = { |
| 519 { check_0, apply_0, 0 }, | 500 { check_0, apply_0, 0 }, |
| 520 { check_1, apply_1, 0 }, | 501 { check_1, apply_1, 0 }, |
| 521 { check_2, apply_2, 0 }, | 502 { check_2, apply_2, 0 }, |
| 522 { check_3, apply_3, 0 }, | 503 { check_3, apply_3, 0 }, |
| 523 { check_4, apply_4, 0 }, | 504 { check_4, apply_4, 0 }, |
| 524 { check_5, apply_5, 0 }, | 505 { check_5, apply_5, 0 }, |
| 525 { check_6, apply_6, 0 }, | 506 { check_6, apply_6, 0 }, |
| 526 { check_7, apply_7, 0 }, | 507 { check_7, apply_7, 0 }, |
| 527 }; | 508 }; |
| 528 | 509 |
| 510 |
| 529 static int filter_picture(const SkString& inFile, const SkString& outFile) { | 511 static int filter_picture(const SkString& inFile, const SkString& outFile) { |
| 530 SkPicture* inPicture = NULL; | 512 SkPicture* inPicture = NULL; |
| 531 | 513 |
| 532 SkFILEStream inStream(inFile.c_str()); | 514 SkFILEStream inStream(inFile.c_str()); |
| 533 if (inStream.isValid()) { | 515 if (inStream.isValid()) { |
| 534 inPicture = SkNEW_ARGS(SkPicture, (&inStream, NULL, &SkImageDecoder::Dec
odeMemory)); | 516 inPicture = SkNEW_ARGS(SkPicture, (&inStream, NULL, &SkImageDecoder::Dec
odeMemory)); |
| 535 } | 517 } |
| 536 | 518 |
| 537 if (NULL == inPicture) { | 519 if (NULL == inPicture) { |
| 538 SkDebugf("Could not read file %s\n", inFile.c_str()); | 520 SkDebugf("Could not read file %s\n", inFile.c_str()); |
| 539 return -1; | 521 return -1; |
| 540 } | 522 } |
| 541 | 523 |
| 542 int localCount[SK_ARRAY_COUNT(gOptTable)]; | 524 int localCount[SK_ARRAY_COUNT(gOptTable)]; |
| 543 | 525 |
| 544 memset(localCount, 0, sizeof(localCount)); | 526 memset(localCount, 0, sizeof(localCount)); |
| 545 | 527 |
| 546 SkDebugCanvas debugCanvas(inPicture->width(), inPicture->height()); | 528 SkDebugCanvas debugCanvas(inPicture->width(), inPicture->height()); |
| 547 debugCanvas.setBounds(inPicture->width(), inPicture->height()); | 529 debugCanvas.setBounds(inPicture->width(), inPicture->height()); |
| 548 inPicture->draw(&debugCanvas); | 530 inPicture->draw(&debugCanvas); |
| 549 | 531 |
| 550 SkTDArray<SkDrawCommand*>& commands = debugCanvas.getDrawCommands(); | 532 // delete the initial save and restore since replaying the commands will |
| 551 | |
| 552 // hide the initial save and restore since replaying the commands will | |
| 553 // re-add them | 533 // re-add them |
| 554 if (commands.count() > 0) { | 534 if (debugCanvas.getSize() > 1) { |
| 555 commands[0]->setVisible(false); | 535 debugCanvas.deleteDrawCommandAt(0); |
| 556 commands[commands.count()-1]->setVisible(false); | 536 debugCanvas.deleteDrawCommandAt(debugCanvas.getSize()-1); |
| 557 } | 537 } |
| 558 | 538 |
| 559 for (int i = 0; i < commands.count(); ++i) { | 539 for (int i = 0; i < debugCanvas.getSize(); ++i) { |
| 560 for (size_t opt = 0; opt < SK_ARRAY_COUNT(gOptTable); ++opt) { | 540 for (size_t opt = 0; opt < SK_ARRAY_COUNT(gOptTable); ++opt) { |
| 561 if ((*gOptTable[opt].fCheck)(commands, i)) { | 541 if ((*gOptTable[opt].fCheck)(&debugCanvas, i)) { |
| 562 (*gOptTable[opt].fApply)(commands, i); | 542 (*gOptTable[opt].fApply)(&debugCanvas, i); |
| 563 ++gOptTable[opt].fNumTimesApplied; | 543 ++gOptTable[opt].fNumTimesApplied; |
| 564 ++localCount[opt]; | 544 ++localCount[opt]; |
| 565 } | 545 } |
| 566 } | 546 } |
| 567 } | 547 } |
| 568 | 548 |
| 569 if (!outFile.isEmpty()) { | 549 if (!outFile.isEmpty()) { |
| 570 SkPicture outPicture; | 550 SkPicture outPicture; |
| 571 | 551 |
| 572 SkCanvas* canvas = outPicture.beginRecording(inPicture->width(), inPictu
re->height()); | 552 SkCanvas* canvas = outPicture.beginRecording(inPicture->width(), inPictu
re->height()); |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 684 | 664 |
| 685 SkGraphics::Term(); | 665 SkGraphics::Term(); |
| 686 return 0; | 666 return 0; |
| 687 } | 667 } |
| 688 | 668 |
| 689 #if !defined SK_BUILD_FOR_IOS | 669 #if !defined SK_BUILD_FOR_IOS |
| 690 int main(int argc, char * const argv[]) { | 670 int main(int argc, char * const argv[]) { |
| 691 return tool_main(argc, (char**) argv); | 671 return tool_main(argc, (char**) argv); |
| 692 } | 672 } |
| 693 #endif | 673 #endif |
| OLD | NEW |