Revert of Fix layer hoisting image filter corner cases (patchset #3 id:40001 of https://codereview.chromium.org/803183003/)
Reason for revert: Breaking DM Original issue's description: > Fix layer hoisting image filter corner cases > > This CL fixes 5 bugs related to hoisting image filters: > > For image filters the src layer (the one prior to filtering) often needs to be > smaller then the final layer. This requires the saveLayer's optional bounds > to be stored (in SkLayerInfo.h and SkRecordDraw.cpp) and then used in > compute_source_rect and carried around in GrCachedLayer. > > The image filters can add an extra offset to the final draw operation. > This is now computed in GrLayerHoister::FilterLayer and carried around in > GrCachedLayer. > > Filtered layers must use exact matches. This is now done in GrLayerCache::lock. > > The filter cache requires a valid matrix so it can compute the correct offset. > This is now done in GrLayerHoister::FilterLayer. > > Filtered layers need to be drawn with drawSprite while unfiltered (and therefore > hopefully atlased) layers can be drawn with drawBitmap. This is now done in > draw_replacement_bitmap. > > Committed: https://skia.googlesource.com/skia/+/702eb9622102599d94ab6798e6227cf29f48c2d3 TBR=bsalomon@google.com NOTREECHECKS=true NOTRY=true Review URL: https://codereview.chromium.org/790643009
This commit is contained in:
parent
861e103701
commit
86f032832f
@ -655,21 +655,18 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
static void generate_image_from_picture(GM* gm, const ConfigData& config,
|
||||
GrSurface* gpuTarget,
|
||||
static void generate_image_from_picture(GM* gm, const ConfigData& gRec,
|
||||
SkPicture* pict, SkBitmap* bitmap,
|
||||
SkScalar scale = SK_Scalar1,
|
||||
bool tile = false) {
|
||||
const SkISize size = gm->getISize();
|
||||
SkISize size = gm->getISize();
|
||||
setup_bitmap(gRec, size, bitmap);
|
||||
|
||||
SkAutoTUnref<SkSurface> surf(CreateSurface(config, size, gpuTarget));
|
||||
SkAutoTUnref<SkSurface> surf(SkSurface::NewRasterDirect(bitmap->info(),
|
||||
bitmap->getPixels(),
|
||||
bitmap->rowBytes()));
|
||||
|
||||
DrawPictureToSurface(surf, pict, scale, tile, false);
|
||||
|
||||
setup_bitmap(config, size, bitmap);
|
||||
|
||||
surf->readPixels(bitmap->info(), bitmap->getPixels(), bitmap->rowBytes(), 0, 0);
|
||||
|
||||
complete_bitmap(bitmap);
|
||||
}
|
||||
|
||||
@ -1633,12 +1630,10 @@ template <typename T> void appendUnique(SkTDArray<T>* array, const T& value) {
|
||||
*
|
||||
* Returns all errors encountered while doing so.
|
||||
*/
|
||||
ErrorCombination run_multiple_modes(GMMain &gmmain, GM *gm,
|
||||
const ConfigData &compareConfig, GrSurface* gpuTarget,
|
||||
ErrorCombination run_multiple_modes(GMMain &gmmain, GM *gm, const ConfigData &compareConfig,
|
||||
const SkBitmap &comparisonBitmap,
|
||||
const SkTDArray<SkScalar> &tileGridReplayScales);
|
||||
ErrorCombination run_multiple_modes(GMMain &gmmain, GM *gm,
|
||||
const ConfigData &compareConfig, GrSurface* gpuTarget,
|
||||
ErrorCombination run_multiple_modes(GMMain &gmmain, GM *gm, const ConfigData &compareConfig,
|
||||
const SkBitmap &comparisonBitmap,
|
||||
const SkTDArray<SkScalar> &tileGridReplayScales) {
|
||||
ErrorCombination errorsForAllModes;
|
||||
@ -1656,8 +1651,7 @@ ErrorCombination run_multiple_modes(GMMain &gmmain, GM *gm,
|
||||
errorsForAllModes.add(kIntentionallySkipped_ErrorType);
|
||||
} else {
|
||||
SkBitmap bitmap;
|
||||
gmmain.generate_image_from_picture(gm, compareConfig, gpuTarget, pict, &bitmap);
|
||||
|
||||
gmmain.generate_image_from_picture(gm, compareConfig, pict, &bitmap);
|
||||
errorsForAllModes.add(gmmain.compare_test_results_to_reference_bitmap(
|
||||
gm->getName(), compareConfig.fName, renderModeDescriptor, bitmap,
|
||||
&comparisonBitmap));
|
||||
@ -1674,7 +1668,7 @@ ErrorCombination run_multiple_modes(GMMain &gmmain, GM *gm,
|
||||
SkPicture* repict = gmmain.stream_to_new_picture(*pict);
|
||||
SkAutoTUnref<SkPicture> aurr(repict);
|
||||
SkBitmap bitmap;
|
||||
gmmain.generate_image_from_picture(gm, compareConfig, gpuTarget, repict, &bitmap);
|
||||
gmmain.generate_image_from_picture(gm, compareConfig, repict, &bitmap);
|
||||
errorsForAllModes.add(gmmain.compare_test_results_to_reference_bitmap(
|
||||
gm->getName(), compareConfig.fName, renderModeDescriptor, bitmap,
|
||||
&comparisonBitmap));
|
||||
@ -1707,7 +1701,7 @@ ErrorCombination run_multiple_modes(GMMain &gmmain, GM *gm,
|
||||
SkPicture* pict = gmmain.generate_new_picture(gm, kRTree_BbhType, 0);
|
||||
SkAutoTUnref<SkPicture> aur(pict);
|
||||
SkBitmap bitmap;
|
||||
gmmain.generate_image_from_picture(gm, compareConfig, gpuTarget, pict, &bitmap);
|
||||
gmmain.generate_image_from_picture(gm, compareConfig, pict, &bitmap);
|
||||
errorsForAllModes.add(gmmain.compare_test_results_to_reference_bitmap(
|
||||
gm->getName(), compareConfig.fName, renderModeDescriptor, bitmap,
|
||||
&comparisonBitmap));
|
||||
@ -1740,7 +1734,7 @@ ErrorCombination run_multiple_modes(GMMain &gmmain, GM *gm,
|
||||
// We cannot yet pass 'true' to generate_image_from_picture to
|
||||
// perform actual tiled rendering (see Issue 1198 -
|
||||
// https://code.google.com/p/skia/issues/detail?id=1198)
|
||||
gmmain.generate_image_from_picture(gm, compareConfig, gpuTarget, pict, &bitmap,
|
||||
gmmain.generate_image_from_picture(gm, compareConfig, pict, &bitmap,
|
||||
replayScale /*, true */);
|
||||
errorsForAllModes.add(gmmain.compare_test_results_to_reference_bitmap(
|
||||
gm->getName(), compareConfig.fName, renderModeDescriptor.c_str(), bitmap,
|
||||
@ -1881,7 +1875,7 @@ ErrorCombination run_multiple_configs(GMMain &gmmain, GM *gm,
|
||||
|
||||
// TODO: run only if gmmain.test_drawing succeeded.
|
||||
if (kRaster_Backend == config.fBackend) {
|
||||
run_multiple_modes(gmmain, gm, config, gpuTarget, comparisonBitmap, tileGridReplayScales);
|
||||
run_multiple_modes(gmmain, gm, config, comparisonBitmap, tileGridReplayScales);
|
||||
}
|
||||
|
||||
if (FLAGS_deferred && errorsForThisConfig.isEmpty() &&
|
||||
|
@ -28,9 +28,6 @@ public:
|
||||
const SkPicture* fPicture;
|
||||
// The device space bounds of this layer.
|
||||
SkRect fBounds;
|
||||
// If not-empty, the optional bounds parameter passed in to the saveLayer
|
||||
// call.
|
||||
SkRect fSrcBounds;
|
||||
// The pre-matrix begins as the identity and accumulates the transforms
|
||||
// of the containing SkPictures (if any). This matrix state has to be
|
||||
// part of the initial matrix during replay so that it will be
|
||||
|
@ -608,26 +608,24 @@ public:
|
||||
private:
|
||||
struct SaveLayerInfo {
|
||||
SaveLayerInfo() { }
|
||||
SaveLayerInfo(int opIndex, bool isSaveLayer, const SkRect* bounds, const SkPaint* paint)
|
||||
SaveLayerInfo(int opIndex, bool isSaveLayer, const SkPaint* paint)
|
||||
: fStartIndex(opIndex)
|
||||
, fIsSaveLayer(isSaveLayer)
|
||||
, fHasNestedSaveLayer(false)
|
||||
, fBounds(bounds ? *bounds : SkRect::MakeEmpty())
|
||||
, fPaint(paint) {
|
||||
}
|
||||
|
||||
int fStartIndex;
|
||||
bool fIsSaveLayer;
|
||||
bool fHasNestedSaveLayer;
|
||||
SkRect fBounds;
|
||||
const SkPaint* fPaint;
|
||||
};
|
||||
|
||||
template <typename T> void trackSaveLayers(const T& op) {
|
||||
/* most ops aren't involved in saveLayers */
|
||||
}
|
||||
void trackSaveLayers(const Save& s) { this->pushSaveLayerInfo(false, NULL, NULL); }
|
||||
void trackSaveLayers(const SaveLayer& sl) { this->pushSaveLayerInfo(true, sl.bounds, sl.paint); }
|
||||
void trackSaveLayers(const Save& s) { this->pushSaveLayerInfo(false, NULL); }
|
||||
void trackSaveLayers(const SaveLayer& sl) { this->pushSaveLayerInfo(true, sl.paint); }
|
||||
void trackSaveLayers(const Restore& r) { this->popSaveLayerInfo(); }
|
||||
|
||||
void trackSaveLayersForPicture(const SkPicture* picture, const SkPaint* paint) {
|
||||
@ -664,7 +662,6 @@ private:
|
||||
dst.fPicture = src.fPicture ? src.fPicture : picture;
|
||||
dst.fPicture->ref();
|
||||
dst.fBounds = newBound;
|
||||
dst.fSrcBounds = src.fSrcBounds;
|
||||
dst.fLocalMat = src.fLocalMat;
|
||||
dst.fPreMat = src.fPreMat;
|
||||
dst.fPreMat.postConcat(fFillBounds.ctm());
|
||||
@ -710,14 +707,14 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
void pushSaveLayerInfo(bool isSaveLayer, const SkRect* bounds, const SkPaint* paint) {
|
||||
void pushSaveLayerInfo(bool isSaveLayer, const SkPaint* paint) {
|
||||
if (isSaveLayer) {
|
||||
this->updateStackForSaveLayer();
|
||||
++fSaveLayersInStack;
|
||||
fSaveLayerOpStack.push(fFillBounds.currentOp());
|
||||
}
|
||||
|
||||
fSaveLayerStack.push(SaveLayerInfo(fFillBounds.currentOp(), isSaveLayer, bounds, paint));
|
||||
fSaveLayerStack.push(SaveLayerInfo(fFillBounds.currentOp(), isSaveLayer, paint));
|
||||
}
|
||||
|
||||
void popSaveLayerInfo() {
|
||||
@ -747,8 +744,6 @@ private:
|
||||
if (sli.fPaint) {
|
||||
block.fPaint = SkNEW_ARGS(SkPaint, (*sli.fPaint));
|
||||
}
|
||||
|
||||
block.fSrcBounds = sli.fBounds;
|
||||
block.fSaveLayerOpID = sli.fStartIndex;
|
||||
block.fRestoreOpID = fFillBounds.currentOp();
|
||||
block.fHasNestedLayers = sli.fHasNestedSaveLayer;
|
||||
|
@ -123,16 +123,14 @@ void GrLayerCache::freeAll() {
|
||||
|
||||
GrCachedLayer* GrLayerCache::createLayer(uint32_t pictureID,
|
||||
int start, int stop,
|
||||
const SkIRect& srcIR,
|
||||
const SkIRect& dstIR,
|
||||
const SkIRect& bounds,
|
||||
const SkMatrix& initialMat,
|
||||
const unsigned* key,
|
||||
int keySize,
|
||||
const SkPaint* paint) {
|
||||
SkASSERT(pictureID != SK_InvalidGenID && start >= 0 && stop > 0);
|
||||
|
||||
GrCachedLayer* layer = SkNEW_ARGS(GrCachedLayer, (pictureID, start, stop,
|
||||
srcIR, dstIR, initialMat,
|
||||
GrCachedLayer* layer = SkNEW_ARGS(GrCachedLayer, (pictureID, start, stop, bounds, initialMat,
|
||||
key, keySize, paint));
|
||||
fLayerHash.add(layer);
|
||||
return layer;
|
||||
@ -146,8 +144,7 @@ GrCachedLayer* GrLayerCache::findLayer(uint32_t pictureID, const SkMatrix& initi
|
||||
|
||||
GrCachedLayer* GrLayerCache::findLayerOrCreate(uint32_t pictureID,
|
||||
int start, int stop,
|
||||
const SkIRect& srcIR,
|
||||
const SkIRect& dstIR,
|
||||
const SkIRect& bounds,
|
||||
const SkMatrix& initialMat,
|
||||
const unsigned* key,
|
||||
int keySize,
|
||||
@ -155,9 +152,7 @@ GrCachedLayer* GrLayerCache::findLayerOrCreate(uint32_t pictureID,
|
||||
SkASSERT(pictureID != SK_InvalidGenID && start >= 0 && stop > 0);
|
||||
GrCachedLayer* layer = fLayerHash.find(GrCachedLayer::Key(pictureID, initialMat, key, keySize));
|
||||
if (NULL == layer) {
|
||||
layer = this->createLayer(pictureID, start, stop,
|
||||
srcIR, dstIR, initialMat,
|
||||
key, keySize, paint);
|
||||
layer = this->createLayer(pictureID, start, stop, bounds, initialMat, key, keySize, paint);
|
||||
}
|
||||
|
||||
return layer;
|
||||
@ -247,14 +242,8 @@ bool GrLayerCache::lock(GrCachedLayer* layer, const GrSurfaceDesc& desc, bool* n
|
||||
return true;
|
||||
}
|
||||
|
||||
// TODO: make the test for exact match depend on the image filters themselves
|
||||
GrContext::ScratchTexMatch usage = GrContext::kApprox_ScratchTexMatch;
|
||||
if (layer->fFilter) {
|
||||
usage = GrContext::kExact_ScratchTexMatch;
|
||||
}
|
||||
|
||||
SkAutoTUnref<GrTexture> tex(
|
||||
fContext->refScratchTexture(desc, usage));
|
||||
fContext->refScratchTexture(desc, GrContext::kApprox_ScratchTexMatch));
|
||||
|
||||
if (!tex) {
|
||||
return false;
|
||||
|
@ -144,16 +144,13 @@ public:
|
||||
|
||||
// GrCachedLayer proper
|
||||
GrCachedLayer(uint32_t pictureID, unsigned start, unsigned stop,
|
||||
const SkIRect& srcIR, const SkIRect& dstIR,
|
||||
const SkMatrix& ctm,
|
||||
const SkIRect& bounds, const SkMatrix& ctm,
|
||||
const unsigned* key, int keySize,
|
||||
const SkPaint* paint)
|
||||
: fKey(pictureID, ctm, key, keySize, true)
|
||||
, fStart(start)
|
||||
, fStop(stop)
|
||||
, fSrcIR(srcIR)
|
||||
, fDstIR(dstIR)
|
||||
, fOffset(SkIPoint::Make(0, 0))
|
||||
, fBounds(bounds)
|
||||
, fPaint(paint ? SkNEW_ARGS(SkPaint, (*paint)) : NULL)
|
||||
, fFilter(NULL)
|
||||
, fTexture(NULL)
|
||||
@ -164,10 +161,8 @@ public:
|
||||
SkASSERT(SK_InvalidGenID != pictureID);
|
||||
|
||||
if (fPaint) {
|
||||
if (fPaint->getImageFilter() && fPaint->getImageFilter()->canFilterImageGPU()) {
|
||||
fFilter = SkSafeRef(fPaint->getImageFilter());
|
||||
fPaint->setImageFilter(NULL);
|
||||
}
|
||||
fFilter = SkSafeRef(fPaint->getImageFilter());
|
||||
fPaint->setImageFilter(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
@ -184,8 +179,7 @@ public:
|
||||
|
||||
unsigned start() const { return fStart; }
|
||||
// TODO: make bound debug only
|
||||
const SkIRect& srcIR() const { return fSrcIR; }
|
||||
const SkIRect& dstIR() const { return fDstIR; }
|
||||
const SkIRect& bound() const { return fBounds; }
|
||||
unsigned stop() const { return fStop; }
|
||||
void setTexture(GrTexture* texture, const SkIRect& rect) {
|
||||
SkRefCnt_SafeAssign(fTexture, texture);
|
||||
@ -196,9 +190,6 @@ public:
|
||||
const SkImageFilter* filter() const { return fFilter; }
|
||||
const SkIRect& rect() const { return fRect; }
|
||||
|
||||
void setOffset(const SkIPoint& offset) { fOffset = offset; }
|
||||
const SkIPoint& offset() const { return fOffset; }
|
||||
|
||||
void setPlot(GrPlot* plot) {
|
||||
SkASSERT(NULL == plot || NULL == fPlot);
|
||||
fPlot = plot;
|
||||
@ -221,13 +212,7 @@ private:
|
||||
// The final "restore" operation index of the cached layer
|
||||
const unsigned fStop;
|
||||
|
||||
// The layer's src rect (i.e., the portion of the source scene required
|
||||
// for filtering).
|
||||
const SkIRect fSrcIR;
|
||||
// The layer's dest rect (i.e., where it will land in device space)
|
||||
const SkIRect fDstIR;
|
||||
// Offset sometimes required by image filters
|
||||
SkIPoint fOffset;
|
||||
const SkIRect fBounds;
|
||||
|
||||
// The paint used when dropping the layer down into the owning canvas.
|
||||
// Can be NULL. This class makes a copy for itself.
|
||||
@ -291,8 +276,7 @@ public:
|
||||
const unsigned* key, int keySize);
|
||||
GrCachedLayer* findLayerOrCreate(uint32_t pictureID,
|
||||
int start, int stop,
|
||||
const SkIRect& srcIR,
|
||||
const SkIRect& dstIR,
|
||||
const SkIRect& bounds,
|
||||
const SkMatrix& initialMat,
|
||||
const unsigned* key, int keySize,
|
||||
const SkPaint* paint);
|
||||
@ -376,8 +360,7 @@ private:
|
||||
|
||||
void initAtlas();
|
||||
GrCachedLayer* createLayer(uint32_t pictureID, int start, int stop,
|
||||
const SkIRect& srcIR, const SkIRect& dstIR,
|
||||
const SkMatrix& initialMat,
|
||||
const SkIRect& bounds, const SkMatrix& initialMat,
|
||||
const unsigned* key, int keySize,
|
||||
const SkPaint* paint);
|
||||
|
||||
|
@ -23,8 +23,7 @@ static void prepare_for_hoisting(GrLayerCache* layerCache,
|
||||
const SkPicture* topLevelPicture,
|
||||
const SkMatrix& initialMat,
|
||||
const SkLayerInfo::BlockInfo& info,
|
||||
const SkIRect& srcIR,
|
||||
const SkIRect& dstIR,
|
||||
const SkIRect& layerRect,
|
||||
SkTDArray<GrHoistedLayer>* needRendering,
|
||||
SkTDArray<GrHoistedLayer>* recycled,
|
||||
bool attemptToAtlas,
|
||||
@ -34,16 +33,15 @@ static void prepare_for_hoisting(GrLayerCache* layerCache,
|
||||
GrCachedLayer* layer = layerCache->findLayerOrCreate(topLevelPicture->uniqueID(),
|
||||
SkToInt(info.fSaveLayerOpID),
|
||||
SkToInt(info.fRestoreOpID),
|
||||
srcIR,
|
||||
dstIR,
|
||||
layerRect,
|
||||
initialMat,
|
||||
info.fKey,
|
||||
info.fKeySize,
|
||||
info.fPaint);
|
||||
GrSurfaceDesc desc;
|
||||
desc.fFlags = kRenderTarget_GrSurfaceFlag;
|
||||
desc.fWidth = srcIR.width();
|
||||
desc.fHeight = srcIR.height();
|
||||
desc.fWidth = layerRect.width();
|
||||
desc.fHeight = layerRect.height();
|
||||
desc.fConfig = kSkia8888_GrPixelConfig;
|
||||
desc.fSampleCnt = numSamples;
|
||||
|
||||
@ -82,40 +80,6 @@ static void prepare_for_hoisting(GrLayerCache* layerCache,
|
||||
hl->fPreMat.preConcat(info.fPreMat);
|
||||
}
|
||||
|
||||
// Compute the source rect if possible and return false if further processing
|
||||
// on the layer should be abandoned based on its source rect.
|
||||
static bool compute_source_rect(const SkLayerInfo::BlockInfo& info, const SkMatrix& initialMat,
|
||||
const SkIRect& dstIR, SkIRect* srcIR) {
|
||||
SkIRect clipBounds = dstIR;
|
||||
|
||||
SkMatrix totMat = initialMat;
|
||||
totMat.preConcat(info.fPreMat);
|
||||
totMat.preConcat(info.fLocalMat);
|
||||
|
||||
if (info.fPaint && info.fPaint->getImageFilter()) {
|
||||
info.fPaint->getImageFilter()->filterBounds(clipBounds, totMat, &clipBounds);
|
||||
}
|
||||
|
||||
if (!info.fSrcBounds.isEmpty()) {
|
||||
SkRect r;
|
||||
|
||||
totMat.mapRect(&r, info.fSrcBounds);
|
||||
r.roundOut(srcIR);
|
||||
|
||||
if (!srcIR->intersect(clipBounds)) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
*srcIR = clipBounds;
|
||||
}
|
||||
|
||||
if (!GrLayerCache::PlausiblyAtlasable(srcIR->width(), srcIR->height())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Atlased layers must be small enough to fit in the atlas, not have a
|
||||
// paint with an image filter and be neither nested nor nesting.
|
||||
// TODO: allow leaf nested layers to appear in the atlas.
|
||||
@ -166,16 +130,14 @@ void GrLayerHoister::FindLayersToAtlas(GrContext* context,
|
||||
continue;
|
||||
}
|
||||
|
||||
const SkIRect dstIR = layerRect.roundOut();
|
||||
const SkIRect ir = layerRect.roundOut();
|
||||
|
||||
SkIRect srcIR;
|
||||
|
||||
if (!compute_source_rect(info, initialMat, dstIR, &srcIR)) {
|
||||
if (!GrLayerCache::PlausiblyAtlasable(ir.width(), ir.height())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
prepare_for_hoisting(layerCache, topLevelPicture, initialMat,
|
||||
info, srcIR, dstIR, atlased, recycled, true, 0);
|
||||
info, ir, atlased, recycled, true, 0);
|
||||
}
|
||||
|
||||
}
|
||||
@ -217,14 +179,9 @@ void GrLayerHoister::FindLayersToHoist(GrContext* context,
|
||||
continue;
|
||||
}
|
||||
|
||||
const SkIRect dstIR = layerRect.roundOut();
|
||||
const SkIRect ir = layerRect.roundOut();
|
||||
|
||||
SkIRect srcIR;
|
||||
if (!compute_source_rect(info, initialMat, dstIR, &srcIR)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
prepare_for_hoisting(layerCache, topLevelPicture, initialMat, info, srcIR, dstIR,
|
||||
prepare_for_hoisting(layerCache, topLevelPicture, initialMat, info, ir,
|
||||
needRendering, recycled, false, numSamples);
|
||||
}
|
||||
}
|
||||
@ -241,7 +198,7 @@ void GrLayerHoister::DrawLayersToAtlas(GrContext* context,
|
||||
for (int i = 0; i < atlased.count(); ++i) {
|
||||
const GrCachedLayer* layer = atlased[i].fLayer;
|
||||
const SkPicture* pict = atlased[i].fPicture;
|
||||
const SkIPoint offset = SkIPoint::Make(layer->srcIR().fLeft, layer->srcIR().fTop);
|
||||
const SkIPoint offset = SkIPoint::Make(layer->bound().fLeft, layer->bound().fTop);
|
||||
SkDEBUGCODE(const SkPaint* layerPaint = layer->paint();)
|
||||
|
||||
SkASSERT(!layerPaint || !layerPaint->getImageFilter());
|
||||
@ -277,51 +234,42 @@ void GrLayerHoister::DrawLayersToAtlas(GrContext* context,
|
||||
}
|
||||
}
|
||||
|
||||
void GrLayerHoister::FilterLayer(GrContext* context,
|
||||
SkGpuDevice* device,
|
||||
const GrHoistedLayer& info) {
|
||||
GrCachedLayer* layer = info.fLayer;
|
||||
|
||||
void GrLayerHoister::FilterLayer(GrContext* context, SkGpuDevice* device, GrCachedLayer* layer) {
|
||||
SkASSERT(layer->filter());
|
||||
SkASSERT(layer->filter()->canFilterImageGPU());
|
||||
|
||||
static const int kDefaultCacheSize = 32 * 1024 * 1024;
|
||||
|
||||
SkBitmap filteredBitmap;
|
||||
SkIPoint offset = SkIPoint::Make(0, 0);
|
||||
if (layer->filter()->canFilterImageGPU()) {
|
||||
SkBitmap filteredBitmap;
|
||||
SkIPoint offset = SkIPoint::Make(0, 0);
|
||||
|
||||
const SkIPoint filterOffset = SkIPoint::Make(layer->srcIR().fLeft, layer->srcIR().fTop);
|
||||
SkASSERT(0 == layer->rect().fLeft && 0 == layer->rect().fTop);
|
||||
SkIRect clipBounds = layer->rect();
|
||||
|
||||
SkMatrix totMat = SkMatrix::I();
|
||||
totMat.preConcat(info.fPreMat);
|
||||
totMat.preConcat(info.fLocalMat);
|
||||
totMat.postTranslate(-SkIntToScalar(filterOffset.fX), -SkIntToScalar(filterOffset.fY));
|
||||
// This cache is transient, and is freed (along with all its contained
|
||||
// textures) when it goes out of scope.
|
||||
SkAutoTUnref<SkImageFilter::Cache> cache(SkImageFilter::Cache::Create(kDefaultCacheSize));
|
||||
SkImageFilter::Context filterContext(SkMatrix::I(), clipBounds, cache);
|
||||
|
||||
if (!device->filterTexture(context, layer->texture(), layer->filter(),
|
||||
filterContext, &filteredBitmap, &offset)) {
|
||||
// Filtering failed. Press on with the unfiltered version
|
||||
return;
|
||||
}
|
||||
|
||||
SkASSERT(0 == layer->rect().fLeft && 0 == layer->rect().fTop);
|
||||
SkIRect clipBounds = layer->rect();
|
||||
// TODO: need to fix up offset
|
||||
SkASSERT(0 == offset.fX && 0 == offset.fY);
|
||||
|
||||
// This cache is transient, and is freed (along with all its contained
|
||||
// textures) when it goes out of scope.
|
||||
SkAutoTUnref<SkImageFilter::Cache> cache(SkImageFilter::Cache::Create(kDefaultCacheSize));
|
||||
SkImageFilter::Context filterContext(totMat, clipBounds, cache);
|
||||
|
||||
if (!device->filterTexture(context, layer->texture(), layer->filter(),
|
||||
filterContext, &filteredBitmap, &offset)) {
|
||||
// Filtering failed. Press on with the unfiltered version
|
||||
return;
|
||||
SkIRect newRect = SkIRect::MakeWH(filteredBitmap.width(), filteredBitmap.height());
|
||||
layer->setTexture(filteredBitmap.getTexture(), newRect);
|
||||
}
|
||||
|
||||
SkIRect newRect = SkIRect::MakeWH(filteredBitmap.width(), filteredBitmap.height());
|
||||
layer->setTexture(filteredBitmap.getTexture(), newRect);
|
||||
layer->setOffset(offset);
|
||||
}
|
||||
|
||||
void GrLayerHoister::DrawLayers(GrContext* context, const SkTDArray<GrHoistedLayer>& layers) {
|
||||
for (int i = 0; i < layers.count(); ++i) {
|
||||
GrCachedLayer* layer = layers[i].fLayer;
|
||||
const SkPicture* pict = layers[i].fPicture;
|
||||
const SkIPoint offset = SkIPoint::Make(layer->srcIR().fLeft, layer->srcIR().fTop);
|
||||
const SkIPoint offset = SkIPoint::Make(layer->bound().fLeft, layer->bound().fTop);
|
||||
|
||||
// Each non-atlased layer has its own GrTexture
|
||||
SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTargetDirect(
|
||||
@ -353,7 +301,7 @@ void GrLayerHoister::DrawLayers(GrContext* context, const SkTDArray<GrHoistedLay
|
||||
if (layer->filter()) {
|
||||
SkSurface_Gpu* gpuSurf = static_cast<SkSurface_Gpu*>(surface.get());
|
||||
|
||||
FilterLayer(context, gpuSurf->getDevice(), layers[i]);
|
||||
FilterLayer(context, gpuSurf->getDevice(), layer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -108,9 +108,9 @@ private:
|
||||
/** Update the GrTexture in 'layer' with its filtered version
|
||||
@param context Owner of the layer cache (and thus the layers)
|
||||
@param device Required by the filtering code
|
||||
@param info Layer info for a layer needing filtering prior to being composited
|
||||
@param layer A layer needing filtering prior to being composited
|
||||
*/
|
||||
static void FilterLayer(GrContext* context, SkGpuDevice* device, const GrHoistedLayer& info);
|
||||
static void FilterLayer(GrContext* context, SkGpuDevice* device, GrCachedLayer* layer);
|
||||
|
||||
};
|
||||
|
||||
|
@ -21,6 +21,8 @@ static inline void wrap_texture(GrTexture* texture, int width, int height, SkBit
|
||||
}
|
||||
|
||||
static inline void draw_replacement_bitmap(GrCachedLayer* layer, SkCanvas* canvas) {
|
||||
const SkRect src = SkRect::Make(layer->rect());
|
||||
const SkRect dst = SkRect::Make(layer->bound());
|
||||
|
||||
SkBitmap bm;
|
||||
wrap_texture(layer->texture(),
|
||||
@ -28,22 +30,10 @@ static inline void draw_replacement_bitmap(GrCachedLayer* layer, SkCanvas* canva
|
||||
!layer->isAtlased() ? layer->rect().height() : layer->texture()->height(),
|
||||
&bm);
|
||||
|
||||
if (layer->isAtlased()) {
|
||||
const SkRect src = SkRect::Make(layer->rect());
|
||||
const SkRect dst = SkRect::Make(layer->srcIR());
|
||||
|
||||
SkASSERT(layer->offset().isZero());
|
||||
|
||||
canvas->save();
|
||||
canvas->setMatrix(SkMatrix::I());
|
||||
canvas->drawBitmapRectToRect(bm, &src, dst, layer->paint());
|
||||
canvas->restore();
|
||||
} else {
|
||||
canvas->drawSprite(bm,
|
||||
layer->srcIR().fLeft + layer->offset().fX,
|
||||
layer->srcIR().fTop + layer->offset().fY,
|
||||
layer->paint());
|
||||
}
|
||||
canvas->save();
|
||||
canvas->setMatrix(SkMatrix::I());
|
||||
canvas->drawBitmapRectToRect(bm, &src, dst, layer->paint());
|
||||
canvas->restore();
|
||||
}
|
||||
|
||||
// Used by GrRecordReplaceDraw. It intercepts nested drawPicture calls and
|
||||
|
@ -43,7 +43,6 @@ static void create_layers(skiatest::Reporter* reporter,
|
||||
GrCachedLayer* layer = cache->findLayerOrCreate(picture.uniqueID(),
|
||||
idOffset+i+1, idOffset+i+2,
|
||||
SkIRect::MakeEmpty(),
|
||||
SkIRect::MakeEmpty(),
|
||||
SkMatrix::I(),
|
||||
indices, 1,
|
||||
NULL);
|
||||
|
@ -113,7 +113,6 @@ void test_replacements(skiatest::Reporter* r, GrContext* context, bool useBBH) {
|
||||
SkPaint paint;
|
||||
GrLayerCache* layerCache = context->getLayerCache();
|
||||
GrCachedLayer* layer = layerCache->findLayerOrCreate(pic->uniqueID(), 0, 2,
|
||||
SkIRect::MakeWH(kWidth, kHeight),
|
||||
SkIRect::MakeWH(kWidth, kHeight),
|
||||
SkMatrix::I(), key, 1, &paint);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user