Index: src/image/SkSurface_Gpu.cpp |
diff --git a/src/image/SkSurface_Gpu.cpp b/src/image/SkSurface_Gpu.cpp |
index e58375b53b09c4bd43741ac230a58be8c1656004..6cd741d149e77ac0af4dd119beb5f7660f74fda4 100644 |
--- a/src/image/SkSurface_Gpu.cpp |
+++ b/src/image/SkSurface_Gpu.cpp |
@@ -5,27 +5,22 @@ |
* found in the LICENSE file. |
*/ |
-#include "SkSurface_Base.h" |
-#include "SkImagePriv.h" |
-#include "SkImage_Base.h" |
+#include "SkSurface_Gpu.h" |
+ |
+#include "GrGpuResourceCacheAccess.h" |
#include "SkCanvas.h" |
#include "SkGpuDevice.h" |
-#include "SkSurface_Gpu.h" |
+#include "SkImage_Base.h" |
+#include "SkImagePriv.h" |
+#include "SkSurface_Base.h" |
#if SK_SUPPORT_GPU |
/////////////////////////////////////////////////////////////////////////////// |
-SkSurface_Gpu::SkSurface_Gpu(GrRenderTarget* renderTarget, const SkSurfaceProps* props, |
- bool doClear) |
- : INHERITED(renderTarget->width(), renderTarget->height(), props) { |
- int deviceFlags = 0; |
- deviceFlags |= this->props().isUseDistanceFieldFonts() ? SkGpuDevice::kDFText_Flag : 0; |
- fDevice = SkGpuDevice::Create(renderTarget, this->props(), deviceFlags); |
- |
- if (kRGB_565_GrPixelConfig != renderTarget->config() && doClear) { |
- fDevice->clearAll(); |
- } |
+SkSurface_Gpu::SkSurface_Gpu(SkGpuDevice* device) |
+ : INHERITED(device->width(), device->height(), &device->surfaceProps()) |
+ , fDevice(SkRef(device)) { |
} |
SkSurface_Gpu::~SkSurface_Gpu() { |
@@ -43,7 +38,10 @@ SkCanvas* SkSurface_Gpu::onNewCanvas() { |
SkSurface* SkSurface_Gpu::onNewSurface(const SkImageInfo& info) { |
GrRenderTarget* rt = fDevice->accessRenderTarget(); |
int sampleCount = rt->numSamples(); |
- return SkSurface::NewRenderTarget(fDevice->context(), info, sampleCount, &this->props()); |
+ // TODO: Make caller specify this (change virtual signature of onNewSurface). |
+ static const Budgeted kBudgeted = kNo_Budgeted; |
+ return SkSurface::NewRenderTarget(fDevice->context(), kBudgeted, info, sampleCount, |
+ &this->props()); |
} |
SkImage* SkSurface_Gpu::onNewImageSnapshot() { |
@@ -68,19 +66,26 @@ void SkSurface_Gpu::onCopyOnWrite(ContentChangeMode mode) { |
// are we sharing our render target with the image? |
SkASSERT(this->getCachedImage()); |
if (rt->asTexture() == SkTextureImageGetTexture(this->getCachedImage())) { |
- // We call createCompatibleDevice because it uses the texture cache. This isn't |
- // necessarily correct (http://skbug.com/2252), but never using the cache causes |
- // a Chromium regression. (http://crbug.com/344020) |
- SkGpuDevice* newDevice = fDevice->cloneDevice(this->props()); |
- SkAutoTUnref<SkGpuDevice> aurd(newDevice); |
- if (kRetain_ContentChangeMode == mode) { |
- fDevice->context()->copySurface(newDevice->accessRenderTarget(), rt->asTexture()); |
+ GrRenderTarget* oldRT = this->fDevice->accessRenderTarget(); |
+ SkSurface::Budgeted budgeted = oldRT->cacheAccess().isBudgeted() ? kYes_Budgeted : |
+ kNo_Budgeted; |
+ SkAutoTUnref<SkGpuDevice> newDevice( |
+ SkGpuDevice::Create(oldRT->getContext(), budgeted, fDevice->imageInfo(), |
+ oldRT->numSamples(), &this->props(), 0)); |
+ if (kRetain_ContentChangeMode == mode && !oldRT->wasDestroyed() && newDevice) { |
+ oldRT->getContext()->copySurface(newDevice->accessRenderTarget(), oldRT); |
} |
+ |
SkASSERT(this->getCachedCanvas()); |
SkASSERT(this->getCachedCanvas()->getDevice() == fDevice); |
this->getCachedCanvas()->setRootDevice(newDevice); |
- SkRefCnt_SafeAssign(fDevice, newDevice); |
+ SkRefCnt_SafeAssign(fDevice, newDevice.get()); |
+ |
+ // For now we always treat the image snapshots as budgeted. We could make newImageSnapshot |
+ // take a Budgeted param. |
+ oldRT->cacheAccess().makeBudgeted(); |
+ |
} else if (kDiscard_ContentChangeMode == mode) { |
this->SkSurface_Gpu::onDiscard(); |
} |
@@ -93,53 +98,21 @@ void SkSurface_Gpu::onDiscard() { |
/////////////////////////////////////////////////////////////////////////////// |
SkSurface* SkSurface::NewRenderTargetDirect(GrRenderTarget* target, const SkSurfaceProps* props) { |
- if (NULL == target) { |
+ SkAutoTUnref<SkGpuDevice> device(SkGpuDevice::Create(target, props)); |
+ if (!device) { |
return NULL; |
} |
- return SkNEW_ARGS(SkSurface_Gpu, (target, props, false)); |
+ return SkNEW_ARGS(SkSurface_Gpu, (device)); |
} |
-SkSurface* SkSurface::NewRenderTarget(GrContext* ctx, const SkImageInfo& info, int sampleCount, |
- const SkSurfaceProps* props) { |
- if (NULL == ctx) { |
+SkSurface* SkSurface::NewRenderTarget(GrContext* ctx, Budgeted budgeted, const SkImageInfo& info, |
+ int sampleCount, const SkSurfaceProps* props) { |
+ SkAutoTUnref<SkGpuDevice> device(SkGpuDevice::Create(ctx, budgeted, info, sampleCount, props, |
+ SkGpuDevice::kNeedClear_Flag)); |
+ if (!device) { |
return NULL; |
} |
- |
- GrSurfaceDesc desc; |
- desc.fFlags = kRenderTarget_GrSurfaceFlag | kCheckAllocation_GrSurfaceFlag; |
- desc.fWidth = info.width(); |
- desc.fHeight = info.height(); |
- desc.fConfig = SkImageInfo2GrPixelConfig(info); |
- desc.fSampleCnt = sampleCount; |
- |
- SkAutoTUnref<GrTexture> tex(ctx->createUncachedTexture(desc, NULL, 0)); |
- if (NULL == tex) { |
- return NULL; |
- } |
- |
- return SkNEW_ARGS(SkSurface_Gpu, (tex->asRenderTarget(), props, true)); |
-} |
- |
-SkSurface* SkSurface::NewScratchRenderTarget(GrContext* ctx, const SkImageInfo& info, |
- int sampleCount, const SkSurfaceProps* props) { |
- if (NULL == ctx) { |
- return NULL; |
- } |
- |
- GrSurfaceDesc desc; |
- desc.fFlags = kRenderTarget_GrSurfaceFlag | kCheckAllocation_GrSurfaceFlag; |
- desc.fWidth = info.width(); |
- desc.fHeight = info.height(); |
- desc.fConfig = SkImageInfo2GrPixelConfig(info); |
- desc.fSampleCnt = sampleCount; |
- |
- SkAutoTUnref<GrTexture> tex(ctx->refScratchTexture(desc, GrContext::kExact_ScratchTexMatch)); |
- |
- if (NULL == tex) { |
- return NULL; |
- } |
- |
- return SkNEW_ARGS(SkSurface_Gpu, (tex->asRenderTarget(), props, true)); |
+ return SkNEW_ARGS(SkSurface_Gpu, (device)); |
} |
#endif |