18ddc26b68c4e41199c06961da3bff2ce72afff14commit-bot@chromium.org/* 28ddc26b68c4e41199c06961da3bff2ce72afff14commit-bot@chromium.org * Copyright 2014 Google Inc. 38ddc26b68c4e41199c06961da3bff2ce72afff14commit-bot@chromium.org * 48ddc26b68c4e41199c06961da3bff2ce72afff14commit-bot@chromium.org * Use of this source code is governed by a BSD-style license that can be 58ddc26b68c4e41199c06961da3bff2ce72afff14commit-bot@chromium.org * found in the LICENSE file. 68ddc26b68c4e41199c06961da3bff2ce72afff14commit-bot@chromium.org */ 78ddc26b68c4e41199c06961da3bff2ce72afff14commit-bot@chromium.org 88ddc26b68c4e41199c06961da3bff2ce72afff14commit-bot@chromium.org#include "GrPictureUtils.h" 9d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips 100205aba7d5e8802d2a3ef55d999f5aa41db3adc9commit-bot@chromium.org#include "SkPaintPriv.h" 11d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips#include "SkRecord.h" 12d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips#include "SkRecords.h" 130205aba7d5e8802d2a3ef55d999f5aa41db3adc9commit-bot@chromium.org 146617d509ab0b056c57952bb1ee04b4c94904284brobertphillipsSkPicture::AccelData::Key GrAccelData::ComputeAccelDataKey() { 150205aba7d5e8802d2a3ef55d999f5aa41db3adc9commit-bot@chromium.org static const SkPicture::AccelData::Key gGPUID = SkPicture::AccelData::GenerateDomain(); 160205aba7d5e8802d2a3ef55d999f5aa41db3adc9commit-bot@chromium.org 170205aba7d5e8802d2a3ef55d999f5aa41db3adc9commit-bot@chromium.org return gGPUID; 180205aba7d5e8802d2a3ef55d999f5aa41db3adc9commit-bot@chromium.org} 198ddc26b68c4e41199c06961da3bff2ce72afff14commit-bot@chromium.org 20d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips// SkRecord visitor to gather saveLayer/restore information. 21d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillipsclass CollectLayers { 228ddc26b68c4e41199c06961da3bff2ce72afff14commit-bot@chromium.orgpublic: 23d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips CollectLayers(const SkPicture* pict, GrAccelData* accelData) 24d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips : fPictureID(pict->uniqueID()) 25d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips , fCTM(&SkMatrix::I()) 26d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips , fSaveLayersInStack(0) 27d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips , fAccelData(accelData) { 28d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips 29a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips pict->cullRect().roundOut(&fCurrentClipBounds); 30a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips 31d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips if (NULL == pict->fRecord.get()) { 32d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips return; 33d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips } 348ddc26b68c4e41199c06961da3bff2ce72afff14commit-bot@chromium.org 35d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips for (fCurrentOp = 0; fCurrentOp < pict->fRecord->count(); ++fCurrentOp) { 36d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips pict->fRecord->visit<void>(fCurrentOp, *this); 37d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips } 388ddc26b68c4e41199c06961da3bff2ce72afff14commit-bot@chromium.org 39d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips while (!fSaveStack.isEmpty()) { 40d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips this->popSaveBlock(); 41d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips } 428ddc26b68c4e41199c06961da3bff2ce72afff14commit-bot@chromium.org } 438ddc26b68c4e41199c06961da3bff2ce72afff14commit-bot@chromium.org 44d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips template <typename T> void operator()(const T& op) { 45d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips this->updateCTM(op); 46d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips this->updateClipBounds(op); 47d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips this->trackSaveLayers(op); 488ddc26b68c4e41199c06961da3bff2ce72afff14commit-bot@chromium.org } 498ddc26b68c4e41199c06961da3bff2ce72afff14commit-bot@chromium.org 50d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillipsprivate: 518ddc26b68c4e41199c06961da3bff2ce72afff14commit-bot@chromium.org 52d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips class SaveInfo { 53d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips public: 54d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips SaveInfo() { } 55d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips SaveInfo(int opIndex, bool isSaveLayer, const SkPaint* paint, const SkIRect& bounds) 56d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips : fStartIndex(opIndex) 57d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips , fIsSaveLayer(isSaveLayer) 58d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips , fHasNestedSaveLayer(false) 59d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips , fPaint(paint) 60d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips , fBounds(bounds) { 610205aba7d5e8802d2a3ef55d999f5aa41db3adc9commit-bot@chromium.org 62d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips } 630205aba7d5e8802d2a3ef55d999f5aa41db3adc9commit-bot@chromium.org 64d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips int fStartIndex; 65d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips bool fIsSaveLayer; 66d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips bool fHasNestedSaveLayer; 67d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips const SkPaint* fPaint; 68d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips SkIRect fBounds; 69d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips }; 70d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips 71d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips uint32_t fPictureID; 72d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips unsigned int fCurrentOp; 73d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips const SkMatrix* fCTM; 74d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips SkIRect fCurrentClipBounds; 75d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips int fSaveLayersInStack; 76d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips SkTDArray<SaveInfo> fSaveStack; 77d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips GrAccelData* fAccelData; 78d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips 79d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips template <typename T> void updateCTM(const T&) { /* most ops don't change the CTM */ } 80d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips void updateCTM(const SkRecords::Restore& op) { fCTM = &op.matrix; } 81d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips void updateCTM(const SkRecords::SetMatrix& op) { fCTM = &op.matrix; } 82d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips 83d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips template <typename T> void updateClipBounds(const T&) { /* most ops don't change the clip */ } 84d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips // Each of these devBounds fields is the state of the device bounds after the op. 85d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips // So Restore's devBounds are those bounds saved by its paired Save or SaveLayer. 86d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips void updateClipBounds(const SkRecords::Restore& op) { fCurrentClipBounds = op.devBounds; } 87d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips void updateClipBounds(const SkRecords::ClipPath& op) { fCurrentClipBounds = op.devBounds; } 88d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips void updateClipBounds(const SkRecords::ClipRRect& op) { fCurrentClipBounds = op.devBounds; } 89d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips void updateClipBounds(const SkRecords::ClipRect& op) { fCurrentClipBounds = op.devBounds; } 90d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips void updateClipBounds(const SkRecords::ClipRegion& op) { fCurrentClipBounds = op.devBounds; } 91d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips void updateClipBounds(const SkRecords::SaveLayer& op) { 9249f085dddff10473b6ebf832a974288300224e60bsalomon if (op.bounds) { 93d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips fCurrentClipBounds.intersect(this->adjustAndMap(*op.bounds, op.paint)); 940205aba7d5e8802d2a3ef55d999f5aa41db3adc9commit-bot@chromium.org } 95d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips } 960205aba7d5e8802d2a3ef55d999f5aa41db3adc9commit-bot@chromium.org 97d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips template <typename T> void trackSaveLayers(const T& op) { 98d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips /* most ops aren't involved in saveLayers */ 998ddc26b68c4e41199c06961da3bff2ce72afff14commit-bot@chromium.org } 100d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips void trackSaveLayers(const SkRecords::Save& s) { this->pushSaveBlock(); } 101d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips void trackSaveLayers(const SkRecords::SaveLayer& sl) { this->pushSaveLayerBlock(sl.paint); } 102d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips void trackSaveLayers(const SkRecords::Restore& r) { this->popSaveBlock(); } 103d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips void trackSaveLayers(const SkRecords::DrawPicture& dp) { 104d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips // For sub-pictures, we wrap their layer information within the parent 105d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips // picture's rendering hierarchy 106d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips const GrAccelData* childData = GPUOptimize(dp.picture); 107d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips 108d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips for (int i = 0; i < childData->numSaveLayers(); ++i) { 109d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips const GrAccelData::SaveLayerInfo& src = childData->saveLayerInfo(i); 110d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips 111d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips this->updateStackForSaveLayer(); 112d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips 113d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips // TODO: need to store an SkRect in GrAccelData::SaveLayerInfo? 114d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips SkRect srcRect = SkRect::MakeXYWH(SkIntToScalar(src.fOffset.fX), 115d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips SkIntToScalar(src.fOffset.fY), 116d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips SkIntToScalar(src.fSize.width()), 117d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips SkIntToScalar(src.fSize.height())); 118d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips SkIRect newClip(fCurrentClipBounds); 119d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips newClip.intersect(this->adjustAndMap(srcRect, dp.paint)); 120d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips 12130d2cc6ff47cb7f981d83e9a536971beec920f61robertphillips GrAccelData::SaveLayerInfo& dst = fAccelData->addSaveLayerInfo(); 12230d2cc6ff47cb7f981d83e9a536971beec920f61robertphillips 123d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips dst.fValid = true; 12430d2cc6ff47cb7f981d83e9a536971beec920f61robertphillips // If src.fPicture is NULL the layer is in dp.picture; otherwise 12530d2cc6ff47cb7f981d83e9a536971beec920f61robertphillips // it belongs to a sub-picture. 12630d2cc6ff47cb7f981d83e9a536971beec920f61robertphillips dst.fPicture = src.fPicture ? src.fPicture : static_cast<const SkPicture*>(dp.picture); 12730d2cc6ff47cb7f981d83e9a536971beec920f61robertphillips dst.fPicture->ref(); 128d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips dst.fSize = SkISize::Make(newClip.width(), newClip.height()); 129d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips dst.fOffset = SkIPoint::Make(newClip.fLeft, newClip.fTop); 130d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips dst.fOriginXform = *fCTM; 131d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips dst.fOriginXform.postConcat(src.fOriginXform); 13230d2cc6ff47cb7f981d83e9a536971beec920f61robertphillips if (src.fPaint) { 133d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips dst.fPaint = SkNEW_ARGS(SkPaint, (*src.fPaint)); 134d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips } 135d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips dst.fSaveLayerOpID = src.fSaveLayerOpID; 136d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips dst.fRestoreOpID = src.fRestoreOpID; 137d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips dst.fHasNestedLayers = src.fHasNestedLayers; 138d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips dst.fIsNested = fSaveLayersInStack > 0 || src.fIsNested; 139d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips } 1408ddc26b68c4e41199c06961da3bff2ce72afff14commit-bot@chromium.org } 141d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips 142d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips void pushSaveBlock() { 143d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips fSaveStack.push(SaveInfo(fCurrentOp, false, NULL, SkIRect::MakeEmpty())); 1448ddc26b68c4e41199c06961da3bff2ce72afff14commit-bot@chromium.org } 145d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips 146d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips // Inform all the saveLayers already on the stack that they now have a 147d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips // nested saveLayer inside them 148d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips void updateStackForSaveLayer() { 149d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips for (int index = fSaveStack.count() - 1; index >= 0; --index) { 150d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips if (fSaveStack[index].fHasNestedSaveLayer) { 151d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips break; 152d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips } 153d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips fSaveStack[index].fHasNestedSaveLayer = true; 154d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips if (fSaveStack[index].fIsSaveLayer) { 155d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips break; 156d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips } 157d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips } 1588ddc26b68c4e41199c06961da3bff2ce72afff14commit-bot@chromium.org } 1598ddc26b68c4e41199c06961da3bff2ce72afff14commit-bot@chromium.org 160d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips void pushSaveLayerBlock(const SkPaint* paint) { 161d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips this->updateStackForSaveLayer(); 1628ddc26b68c4e41199c06961da3bff2ce72afff14commit-bot@chromium.org 163d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips fSaveStack.push(SaveInfo(fCurrentOp, true, paint, fCurrentClipBounds)); 164d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips ++fSaveLayersInStack; 165d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips } 1668ddc26b68c4e41199c06961da3bff2ce72afff14commit-bot@chromium.org 167d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips void popSaveBlock() { 168d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips if (fSaveStack.count() <= 0) { 169d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips SkASSERT(false); 170d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips return; 171d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips } 1728ddc26b68c4e41199c06961da3bff2ce72afff14commit-bot@chromium.org 173d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips SaveInfo si; 174d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips fSaveStack.pop(&si); 1758ddc26b68c4e41199c06961da3bff2ce72afff14commit-bot@chromium.org 176d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips if (!si.fIsSaveLayer) { 177d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips return; 178d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips } 1798ddc26b68c4e41199c06961da3bff2ce72afff14commit-bot@chromium.org 180d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips --fSaveLayersInStack; 1810205aba7d5e8802d2a3ef55d999f5aa41db3adc9commit-bot@chromium.org 18230d2cc6ff47cb7f981d83e9a536971beec920f61robertphillips GrAccelData::SaveLayerInfo& slInfo = fAccelData->addSaveLayerInfo(); 1838ddc26b68c4e41199c06961da3bff2ce72afff14commit-bot@chromium.org 184d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips slInfo.fValid = true; 18530d2cc6ff47cb7f981d83e9a536971beec920f61robertphillips SkASSERT(NULL == slInfo.fPicture); // This layer is in the top-most picture 186d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips slInfo.fSize = SkISize::Make(si.fBounds.width(), si.fBounds.height()); 187d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips slInfo.fOffset = SkIPoint::Make(si.fBounds.fLeft, si.fBounds.fTop); 188d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips slInfo.fOriginXform = *fCTM; 18930d2cc6ff47cb7f981d83e9a536971beec920f61robertphillips if (si.fPaint) { 190d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips slInfo.fPaint = SkNEW_ARGS(SkPaint, (*si.fPaint)); 191d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips } 192d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips slInfo.fSaveLayerOpID = si.fStartIndex; 193d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips slInfo.fRestoreOpID = fCurrentOp; 194d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips slInfo.fHasNestedLayers = si.fHasNestedSaveLayer; 195d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips slInfo.fIsNested = fSaveLayersInStack > 0; 1968ddc26b68c4e41199c06961da3bff2ce72afff14commit-bot@chromium.org } 1978ddc26b68c4e41199c06961da3bff2ce72afff14commit-bot@chromium.org 198d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips // Returns true if rect was meaningfully adjusted for the effects of paint, 199d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips // false if the paint could affect the rect in unknown ways. 200d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips static bool AdjustForPaint(const SkPaint* paint, SkRect* rect) { 201d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips if (paint) { 202d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips if (paint->canComputeFastBounds()) { 203d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips *rect = paint->computeFastBounds(*rect, rect); 204d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips return true; 205d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips } 206d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips return false; 207d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips } 208d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips return true; 209d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips } 2108ddc26b68c4e41199c06961da3bff2ce72afff14commit-bot@chromium.org 211d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips // Adjust rect for all paints that may affect its geometry, then map it to device space. 212d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips SkIRect adjustAndMap(SkRect rect, const SkPaint* paint) const { 213d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips // Inverted rectangles really confuse our BBHs. 214d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips rect.sort(); 2158ddc26b68c4e41199c06961da3bff2ce72afff14commit-bot@chromium.org 216d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips // Adjust the rect for its own paint. 217d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips if (!AdjustForPaint(paint, &rect)) { 218d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips // The paint could do anything to our bounds. The only safe answer is the current clip. 219d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips return fCurrentClipBounds; 220d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips } 2218ddc26b68c4e41199c06961da3bff2ce72afff14commit-bot@chromium.org 222d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips // Adjust rect for all the paints from the SaveLayers we're inside. 223d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips for (int i = fSaveStack.count() - 1; i >= 0; i--) { 224d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips if (!AdjustForPaint(fSaveStack[i].fPaint, &rect)) { 225d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips // Same deal as above. 226d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips return fCurrentClipBounds; 227d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips } 228d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips } 2298ddc26b68c4e41199c06961da3bff2ce72afff14commit-bot@chromium.org 230d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips // Map the rect back to device space. 231d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips fCTM->mapRect(&rect); 232d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips SkIRect devRect; 233d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips rect.roundOut(&devRect); 2348ddc26b68c4e41199c06961da3bff2ce72afff14commit-bot@chromium.org 235d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips // Nothing can draw outside the current clip. 236d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips // (Only bounded ops call into this method, so oddballs like Clear don't matter here.) 237d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips devRect.intersect(fCurrentClipBounds); 238d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips return devRect; 2399b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillips } 2408ddc26b68c4e41199c06961da3bff2ce72afff14commit-bot@chromium.org}; 2418ddc26b68c4e41199c06961da3bff2ce72afff14commit-bot@chromium.org 242d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips 243d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips// GPUOptimize is only intended to be called within the context of SkGpuDevice's 2442c48ee83c824964fbcb3dc4733055da0e75e154fskia.committer@gmail.com// EXPERIMENTAL_optimize method. 245d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillipsconst GrAccelData* GPUOptimize(const SkPicture* pict) { 246a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips if (NULL == pict || pict->cullRect().isEmpty()) { 247d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips return NULL; 2488ddc26b68c4e41199c06961da3bff2ce72afff14commit-bot@chromium.org } 2498ddc26b68c4e41199c06961da3bff2ce72afff14commit-bot@chromium.org 250d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips SkPicture::AccelData::Key key = GrAccelData::ComputeAccelDataKey(); 251d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips 252d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips const GrAccelData* existing = 253d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips static_cast<const GrAccelData*>(pict->EXPERIMENTAL_getAccelData(key)); 25449f085dddff10473b6ebf832a974288300224e60bsalomon if (existing) { 255d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips return existing; 256d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips } 257d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips 258d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips SkAutoTUnref<GrAccelData> data(SkNEW_ARGS(GrAccelData, (key))); 259d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips 260d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips pict->EXPERIMENTAL_addAccelData(data); 261ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips 262d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips CollectLayers collector(pict, data); 2638ddc26b68c4e41199c06961da3bff2ce72afff14commit-bot@chromium.org 264d62833079fc36e28e65692f9a0c7dbdb124519c6robertphillips return data; 2658ddc26b68c4e41199c06961da3bff2ce72afff14commit-bot@chromium.org} 266