Index: src/gpu/SkGpuDevice.cpp |
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp |
index 3b82a33c9c542dfd95cfd235b6559db788deb5aa..318de8db3d0fd709e7e41daf71c3697242ba1289 100644 |
--- a/src/gpu/SkGpuDevice.cpp |
+++ b/src/gpu/SkGpuDevice.cpp |
@@ -1825,7 +1825,7 @@ static void wrap_texture(GrTexture* texture, int width, int height, SkBitmap* re |
} |
void SkGpuDevice::EXPERIMENTAL_purge(const SkPicture* picture) { |
- |
+ fContext->getLayerCache()->purge(picture); |
} |
bool SkGpuDevice::EXPERIMENTAL_drawPicture(SkCanvas* canvas, const SkPicture* picture) { |
@@ -1951,28 +1951,68 @@ bool SkGpuDevice::EXPERIMENTAL_drawPicture(SkCanvas* canvas, const SkPicture* pi |
// TODO: need to deal with sample count |
bool needsRendering = !fContext->getLayerCache()->lock(layer, desc); |
- if (NULL == layer->getTexture()) { |
+ if (NULL == layer->texture()) { |
continue; |
} |
layerInfo->fBM = SkNEW(SkBitmap); // fBM is allocated so ReplacementInfo can be POD |
- wrap_texture(layer->getTexture(), desc.fWidth, desc.fHeight, layerInfo->fBM); |
+ wrap_texture(layer->texture(), |
+ layer->rect().isEmpty() ? desc.fWidth : layer->texture()->width(), |
+ layer->rect().isEmpty() ? desc.fHeight : layer->texture()->height(), |
+ layerInfo->fBM); |
SkASSERT(info.fPaint); |
layerInfo->fPaint = info.fPaint; |
+ if (layer->rect().isEmpty()) { |
+ layerInfo->fSrcRect = SkIRect::MakeWH(desc.fWidth, desc.fHeight); |
+ } else { |
+ layerInfo->fSrcRect = SkIRect::MakeXYWH(layer->rect().fLeft, |
+ layer->rect().fTop, |
+ layer->rect().width(), |
+ layer->rect().height()); |
+ } |
+ |
if (needsRendering) { |
SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTargetDirect( |
- layer->getTexture()->asRenderTarget())); |
+ layer->texture()->asRenderTarget(), |
+ SkSurface::kStandard_TextRenderMode, |
+ SkSurface::kDontClear_RenderTargetFlag)); |
SkCanvas* canvas = surface->getCanvas(); |
+ if (!layer->rect().isEmpty()) { |
+ // Add a rect clip to make sure the rendering doesn't |
+ // extend beyond the boundaries of the atlased sub-rect |
+ SkRect bound = SkRect::MakeXYWH(SkIntToScalar(layer->rect().fLeft), |
+ SkIntToScalar(layer->rect().fTop), |
+ SkIntToScalar(layer->rect().width()), |
+ SkIntToScalar(layer->rect().height())); |
+ canvas->clipRect(bound); |
+ // Since 'clear' doesn't respect the clip we need to draw a rect |
+ // TODO: ensure none of the atlased layers contain a clear call! |
+ SkPaint paint; |
+ paint.setColor(SK_ColorTRANSPARENT); |
+ canvas->drawRect(bound, paint); |
+ } else { |
+ canvas->clear(SK_ColorTRANSPARENT); |
+ } |
+ |
canvas->setMatrix(info.fCTM); |
- canvas->clear(SK_ColorTRANSPARENT); |
+ |
+ if (!layer->rect().isEmpty()) { |
+ // info.fCTM maps the layer's top/left to the origin. |
+ // Since this layer is atlased the top/left corner needs |
+ // to be offset to some arbitrary location in the backing |
+ // texture. |
+ canvas->translate(SkIntToScalar(layer->rect().fLeft), |
+ SkIntToScalar(layer->rect().fTop)); |
+ } |
picture->fPlayback->setDrawLimits(info.fSaveLayerOpID, info.fRestoreOpID); |
picture->fPlayback->draw(*canvas, NULL); |
picture->fPlayback->setDrawLimits(0, 0); |
+ |
canvas->flush(); |
} |
} |