| OLD | NEW | 
| (Empty) |  | 
 |    1 /* | 
 |    2  * Copyright 2014 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  | 
 |    8 #include "GrRecordReplaceDraw.h" | 
 |    9 #include "SkImage.h" | 
 |   10 #include "SkRecordDraw.h" | 
 |   11  | 
 |   12 GrReplacements::ReplacementInfo* GrReplacements::push() { | 
 |   13     SkDEBUGCODE(this->validate()); | 
 |   14     return fReplacements.push(); | 
 |   15 } | 
 |   16  | 
 |   17 void GrReplacements::freeAll() { | 
 |   18     for (int i = 0; i < fReplacements.count(); ++i) { | 
 |   19         fReplacements[i].fImage->unref(); | 
 |   20     } | 
 |   21     fReplacements.reset(); | 
 |   22 } | 
 |   23  | 
 |   24 #ifdef SK_DEBUG | 
 |   25 void GrReplacements::validate() const { | 
 |   26     // Check that the ranges are monotonically increasing and non-overlapping | 
 |   27     if (fReplacements.count() > 0) { | 
 |   28         SkASSERT(fReplacements[0].fStart < fReplacements[0].fStop); | 
 |   29  | 
 |   30         for (int i = 1; i < fReplacements.count(); ++i) { | 
 |   31             SkASSERT(fReplacements[i].fStart < fReplacements[i].fStop); | 
 |   32             SkASSERT(fReplacements[i - 1].fStop < fReplacements[i].fStart); | 
 |   33         } | 
 |   34     } | 
 |   35 } | 
 |   36 #endif | 
 |   37  | 
 |   38 const GrReplacements::ReplacementInfo* | 
 |   39 GrReplacements::lookupByStart(size_t start, int* searchStart) const { | 
 |   40     SkDEBUGCODE(this->validate()); | 
 |   41     for (int i = *searchStart; i < fReplacements.count(); ++i) { | 
 |   42         if (start == fReplacements[i].fStart) { | 
 |   43             *searchStart = i + 1; | 
 |   44             return &fReplacements[i]; | 
 |   45         } else if (start < fReplacements[i].fStart) { | 
 |   46             return NULL;  // the ranges are monotonically increasing and non-ove
     rlapping | 
 |   47         } | 
 |   48     } | 
 |   49  | 
 |   50     return NULL; | 
 |   51 } | 
 |   52  | 
 |   53 static inline void draw_replacement_bitmap(const GrReplacements::ReplacementInfo
     * ri, | 
 |   54                                            SkCanvas* canvas) { | 
 |   55     SkRect src = SkRect::Make(ri->fSrcRect); | 
 |   56     SkRect dst = SkRect::MakeXYWH(SkIntToScalar(ri->fPos.fX), | 
 |   57                                   SkIntToScalar(ri->fPos.fY), | 
 |   58                                   SkIntToScalar(ri->fSrcRect.width()),  | 
 |   59                                   SkIntToScalar(ri->fSrcRect.height())); | 
 |   60     ri->fImage->draw(canvas, &src, dst, ri->fPaint); | 
 |   61 } | 
 |   62  | 
 |   63 void GrRecordReplaceDraw(const SkRecord& record, | 
 |   64                          SkCanvas* canvas, | 
 |   65                          const SkBBoxHierarchy* bbh, | 
 |   66                          const GrReplacements* replacements, | 
 |   67                          SkDrawPictureCallback* callback) { | 
 |   68     SkAutoCanvasRestore saveRestore(canvas, true /*save now, restore at exit*/); | 
 |   69  | 
 |   70     SkRecords::Draw draw(canvas); | 
 |   71     const GrReplacements::ReplacementInfo* ri = NULL; | 
 |   72     int searchStart = 0; | 
 |   73  | 
 |   74     if (NULL != bbh) { | 
 |   75         // Draw only ops that affect pixels in the canvas's current clip. | 
 |   76         // The SkRecord and BBH were recorded in identity space.  This canvas | 
 |   77         // is not necessarily in that same space.  getClipBounds() returns us | 
 |   78         // this canvas' clip bounds transformed back into identity space, which | 
 |   79         // lets us query the BBH. | 
 |   80         SkRect query = { 0, 0, 0, 0 }; | 
 |   81         (void)canvas->getClipBounds(&query); | 
 |   82  | 
 |   83         SkTDArray<void*> ops; | 
 |   84         bbh->search(query, &ops); | 
 |   85  | 
 |   86         for (int i = 0; i < ops.count(); i++) { | 
 |   87             if (NULL != callback && callback->abortDrawing()) { | 
 |   88                 return; | 
 |   89             } | 
 |   90             ri = replacements->lookupByStart(i, &searchStart); | 
 |   91             if (NULL != ri) { | 
 |   92                 draw_replacement_bitmap(ri, canvas); | 
 |   93  | 
 |   94                 while ((uintptr_t)ops[i] < ri->fStop) { | 
 |   95                     ++i; | 
 |   96                 } | 
 |   97                 SkASSERT((uintptr_t)ops[i] == ri->fStop); | 
 |   98                 continue; | 
 |   99             } | 
 |  100  | 
 |  101             record.visit<void>((uintptr_t)ops[i], draw); | 
 |  102         } | 
 |  103     } else { | 
 |  104         for (unsigned int i = 0; i < record.count(); ++i) { | 
 |  105             if (NULL != callback && callback->abortDrawing()) { | 
 |  106                 return; | 
 |  107             } | 
 |  108             ri = replacements->lookupByStart(i, &searchStart); | 
 |  109             if (NULL != ri) { | 
 |  110                 draw_replacement_bitmap(ri, canvas); | 
 |  111  | 
 |  112                 i = ri->fStop; | 
 |  113                 continue; | 
 |  114             } | 
 |  115  | 
 |  116             record.visit<void>(i, draw); | 
 |  117         } | 
 |  118     } | 
 |  119 } | 
| OLD | NEW |