15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/* 25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright 2014 Google Inc. 35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Use of this source code is governed by a BSD-style license that can be 5197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch * found in the LICENSE file. 65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "GrRecordReplaceDraw.h" 95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "SkImage.h" 105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "SkRecordDraw.h" 115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)GrReplacements::ReplacementInfo* GrReplacements::push() { 135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SkDEBUGCODE(this->validate()); 145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return fReplacements.push(); 155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void GrReplacements::freeAll() { 185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (int i = 0; i < fReplacements.count(); ++i) { 195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) fReplacements[i].fImage->unref(); 205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SkDELETE(fReplacements[i].fPaint); 215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) fReplacements.reset(); 235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 2553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#ifdef SK_DEBUG 26197021e6b966cfb06891637935ef33fff06433d1Ben Murdochvoid GrReplacements::validate() const { 27d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) // Check that the ranges are monotonically increasing and non-overlapping 2853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) if (fReplacements.count() > 0) { 2909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) SkASSERT(fReplacements[0].fStart < fReplacements[0].fStop); 30e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) 3153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) for (int i = 1; i < fReplacements.count(); ++i) { 3209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) SkASSERT(fReplacements[i].fStart < fReplacements[i].fStop); 331e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) SkASSERT(fReplacements[i - 1].fStop < fReplacements[i].fStart); 34e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) } 3553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) } 3653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)} 3709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#endif 3876c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles) 39197021e6b966cfb06891637935ef33fff06433d1Ben Murdochconst GrReplacements::ReplacementInfo* 40f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)GrReplacements::lookupByStart(size_t start, int* searchStart) const { 41f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles) SkDEBUGCODE(this->validate()); 421e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) for (int i = *searchStart; i < fReplacements.count(); ++i) { 43e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) if (start == fReplacements[i].fStart) { 44a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch *searchStart = i + 1; 45197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch return &fReplacements[i]; 4609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) } else if (start < fReplacements[i].fStart) { 47f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles) return NULL; // the ranges are monotonically increasing and non-overlapping 48521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) } 49521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) } 5053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 518abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) return NULL; 52e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)} 53197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static inline void draw_replacement_bitmap(const GrReplacements::ReplacementInfo* ri, 55c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) SkCanvas* canvas, 565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const SkMatrix& initialMatrix) { 5709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) SkRect src = SkRect::Make(ri->fSrcRect); 5809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) SkRect dst = SkRect::MakeXYWH(SkIntToScalar(ri->fPos.fX), 596f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch SkIntToScalar(ri->fPos.fY), 606f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch SkIntToScalar(ri->fSrcRect.width()), 615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SkIntToScalar(ri->fSrcRect.height())); 62197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 63e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) canvas->save(); 645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) canvas->setMatrix(initialMatrix); 655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) canvas->drawImageRect(ri->fImage, &src, dst, ri->fPaint); 6651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) canvas->restore(); 675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 68c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) 69c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)void GrRecordReplaceDraw(const SkRecord& record, 70c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) SkCanvas* canvas, 71c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) const SkBBoxHierarchy* bbh, 725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const GrReplacements* replacements, 735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SkDrawPictureCallback* callback) { 74c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) SkAutoCanvasRestore saveRestore(canvas, true /*save now, restore at exit*/); 75c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) 76c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) SkRecords::Draw draw(canvas); 775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const GrReplacements::ReplacementInfo* ri = NULL; 785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int searchStart = 0; 79323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) 80926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) const SkMatrix initialMatrix = canvas->getTotalMatrix(); 815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 82f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles) if (bbh) { 8319cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles) // Draw only ops that affect pixels in the canvas's current clip. 84197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch // The SkRecord and BBH were recorded in identity space. This canvas 855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // is not necessarily in that same space. getClipBounds() returns us 86323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) // this canvas' clip bounds transformed back into identity space, which 875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // lets us query the BBH. 8819cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles) SkRect query = { 0, 0, 0, 0 }; 895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) (void)canvas->getClipBounds(&query); 90f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles) 9119cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles) SkTDArray<void*> ops; 92f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) bbh->search(query, &ops); 938abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) 945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (int i = 0; i < ops.count(); i++) { 955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (callback && callback->abortDrawing()) { 965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ri = replacements->lookupByStart((uintptr_t)ops[i], &searchStart); 99323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) if (ri) { 100d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) draw_replacement_bitmap(ri, canvas, initialMatrix); 101f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) 102926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) while ((uintptr_t)ops[i] < ri->fStop) { 103323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) ++i; 1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SkASSERT((uintptr_t)ops[i] == ri->fStop); 10651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) continue; 107926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) } 10819cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles) 10951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) record.visit<void>((uintptr_t)ops[i], draw); 110926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) } 111f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles) } else { 11251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) for (unsigned int i = 0; i < record.count(); ++i) { 113926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (callback && callback->abortDrawing()) { 114926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return; 115926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) } 116926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ri = replacements->lookupByStart(i, &searchStart); 117926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (ri) { 11851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) draw_replacement_bitmap(ri, canvas, initialMatrix); 119926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) i = ri->fStop; 12009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) continue; 12151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) } 12251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) 123926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) record.visit<void>(i, draw); 124926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) } 125a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) } 126926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 127e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch