Require budget decision when creating a RenderTarget SkSurface.

Restructure SkGpuDevice creation:
*SkSurfaceProps are optional.
*Use SkSurfaceProps to communicate DF text rather than a flag.
*Tell SkGpuDevice::Create whether RT comes from cache or not.

Review URL: https://codereview.chromium.org/848903004
diff --git a/bench/nanobench.cpp b/bench/nanobench.cpp
index 12686e3..e2fcaaa 100644
--- a/bench/nanobench.cpp
+++ b/bench/nanobench.cpp
@@ -388,7 +388,8 @@
     else if (Benchmark::kGPU_Backend == config.backend) {
         uint32_t flags = config.useDFText ? SkSurfaceProps::kUseDistanceFieldFonts_Flag : 0;
         SkSurfaceProps props(flags, SkSurfaceProps::kLegacyFontHost_InitType);
-        target->surface.reset(SkSurface::NewRenderTarget(gGrFactory->get(config.ctxType), info,
+        target->surface.reset(SkSurface::NewRenderTarget(gGrFactory->get(config.ctxType),
+                                                         SkSurface::kNo_Budgeted, info,
                                                          config.samples, &props));
         target->gl = gGrFactory->getGLContext(config.ctxType);
     }
diff --git a/dm/DMGpuSupport.h b/dm/DMGpuSupport.h
index a513d64..335da08 100644
--- a/dm/DMGpuSupport.h
+++ b/dm/DMGpuSupport.h
@@ -25,7 +25,8 @@
                                        bool useDFText) {
     uint32_t flags = useDFText ? SkSurfaceProps::kUseDistanceFieldFonts_Flag : 0;
     SkSurfaceProps props(flags, SkSurfaceProps::kLegacyFontHost_InitType);
-    return SkSurface::NewRenderTarget(grFactory->get(type, gpuAPI), info, samples, &props);
+    return SkSurface::NewRenderTarget(grFactory->get(type, gpuAPI), SkSurface::kNo_Budgeted,
+                                      info, samples, &props);
 }
 
 }  // namespace DM
diff --git a/expectations/gm/ignored-tests.txt b/expectations/gm/ignored-tests.txt
index 7bc03a3..d806aa4 100644
--- a/expectations/gm/ignored-tests.txt
+++ b/expectations/gm/ignored-tests.txt
@@ -46,3 +46,6 @@
 
 # fmalita - rebaseline for http://crbug.com/447707
 pictureshader
+
+# bsalomon slight change to image-surface GM on gpu
+image-surface
diff --git a/gm/dftext.cpp b/gm/dftext.cpp
index 36b8d55..8ac36cc 100755
--- a/gm/dftext.cpp
+++ b/gm/dftext.cpp
@@ -68,7 +68,8 @@
         SkImageInfo info = SkImageInfo::MakeN32Premul(onISize());
         SkSurfaceProps props(SkSurfaceProps::kUseDistanceFieldFonts_Flag,
                              SkSurfaceProps::kLegacyFontHost_InitType);
-        SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTarget(ctx, info, 0, &props));
+        SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTarget(ctx, SkSurface::kNo_Budgeted,
+                                                                   info, 0, &props));
         SkCanvas* canvas = surface.get() ? surface->getCanvas() : inputCanvas;
         // init our new canvas with the old canvas's matrix
         canvas->setMatrix(inputCanvas->getTotalMatrix());
diff --git a/gm/discard.cpp b/gm/discard.cpp
index 58a0849..19a332f 100644
--- a/gm/discard.cpp
+++ b/gm/discard.cpp
@@ -46,7 +46,7 @@
         size.fWidth /= 10;
         size.fHeight /= 10;
         SkImageInfo info = SkImageInfo::MakeN32Premul(size);
-        SkSurface* surface = SkSurface::NewRenderTarget(context, info);
+        SkSurface* surface = SkSurface::NewRenderTarget(context, SkSurface::kNo_Budgeted, info);
 
         if (NULL == surface) {
             return;
diff --git a/gm/image.cpp b/gm/image.cpp
index d101529..2eaa15d 100644
--- a/gm/image.cpp
+++ b/gm/image.cpp
@@ -177,7 +177,8 @@
 #if SK_SUPPORT_GPU
         GrContext* ctx = canvas->getGrContext();
 
-        SkAutoTUnref<SkSurface> surf4(SkSurface::NewRenderTarget(ctx, info));
+        SkAutoTUnref<SkSurface> surf4(SkSurface::NewRenderTarget(
+            ctx, SkSurface::kNo_Budgeted, info));
 #endif
 
         test_surface(canvas, surf0, true);
diff --git a/gm/surface.cpp b/gm/surface.cpp
index 5961a33..5a4c09a 100644
--- a/gm/surface.cpp
+++ b/gm/surface.cpp
@@ -33,7 +33,7 @@
 
     SkSurfaceProps props(flags, geo);
     if (ctx) {
-        return SkSurface::NewRenderTarget(ctx, info, 0, &props);
+        return SkSurface::NewRenderTarget(ctx, SkSurface::kNo_Budgeted, info, 0, &props);
     } else {
         return SkSurface::NewRaster(info, &props);
     }
diff --git a/gm/xfermodes3.cpp b/gm/xfermodes3.cpp
index c385e41..ffbee1c 100644
--- a/gm/xfermodes3.cpp
+++ b/gm/xfermodes3.cpp
@@ -125,18 +125,13 @@
         SkCanvas* tempCanvas = NULL;
 #if SK_SUPPORT_GPU
         GrContext* context = baseCanvas->getGrContext();
-        if (context) {
-            GrSurfaceDesc desc;
-            desc.fWidth = w;
-            desc.fHeight = h;
-            desc.fConfig = SkImageInfo2GrPixelConfig(baseCanvas->imageInfo());
-            desc.fFlags = kRenderTarget_GrSurfaceFlag;
-            SkAutoTUnref<GrSurface> surface(context->createUncachedTexture(desc, NULL, 0));
-            SkAutoTUnref<SkBaseDevice> device(SkGpuDevice::Create(surface.get(),
-                                          SkSurfaceProps(SkSurfaceProps::kLegacyFontHost_InitType)));
-            if (device.get()) {
-                tempCanvas = SkNEW_ARGS(SkCanvas, (device.get()));
-            }
+        SkImageInfo baseInfo = baseCanvas->imageInfo();
+        SkImageInfo info = SkImageInfo::Make(w, h, baseInfo.colorType(), baseInfo.alphaType(),
+                                             baseInfo.profileType());
+        SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTarget(context, SkSurface::kNo_Budgeted,
+                                        info, 0, NULL));
+        if (surface) {
+            tempCanvas = SkRef(surface->getCanvas());
         }
 #endif
         return tempCanvas;
diff --git a/include/core/SkSurface.h b/include/core/SkSurface.h
index aa1e2cc..1fd345a 100644
--- a/include/core/SkSurface.h
+++ b/include/core/SkSurface.h
@@ -33,6 +33,18 @@
     SK_DECLARE_INST_COUNT(SkSurface)
 
     /**
+     *  Indicates whether a new surface or image should count against a cache budget. Currently this
+     *  is only used by the GPU backend (sw-raster surfaces and images are never counted against the
+     *  resource cache budget.)
+     */
+    enum Budgeted {
+        /** The surface or image does not count against the cache budget. */
+        kNo_Budgeted,
+        /** The surface or image counts against the cache budget. */
+        kYes_Budgeted
+    };
+
+    /**
      *  Create a new surface, using the specified pixels/rowbytes as its
      *  backend.
      *
@@ -86,30 +98,27 @@
      *  Return a new surface whose contents will be drawn to an offscreen
      *  render target, allocated by the surface.
      */
-    static SkSurface* NewRenderTarget(GrContext*, const SkImageInfo&, int sampleCount,
+    static SkSurface* NewRenderTarget(GrContext*, Budgeted, const SkImageInfo&, int sampleCount,
                                       const SkSurfaceProps* = NULL);
 
-    static SkSurface* NewRenderTarget(GrContext* gr, const SkImageInfo& info) {
-        return NewRenderTarget(gr, info, 0, NULL);
+    static SkSurface* NewRenderTarget(GrContext* gr, Budgeted b, const SkImageInfo& info) {
+        return NewRenderTarget(gr, b, info, 0, NULL);
     }
 
     /**
-     *  Return a new surface whose contents will be drawn to an offscreen
-     *  render target, allocated by the surface from the scratch texture pool
-     *  managed by the GrContext. The scratch texture pool serves the purpose
-     *  of retaining textures after they are no longer in use in order to
-     *  re-use them later without having to re-allocate.  Scratch textures
-     *  should be used in cases where high turnover is expected. This allows,
-     *  for example, the copy on write to recycle a texture from a recently
-     *  released SkImage snapshot of the surface.
-     *  Note: Scratch textures count against the GrContext's cached resource
-     *  budget.
+     * Deprecated - use the Budgeted param on NewRenderTarget.
      */
-    static SkSurface* NewScratchRenderTarget(GrContext*, const SkImageInfo&, int sampleCount,
-                                             const SkSurfaceProps* = NULL);
+    static SkSurface* NewScratchRenderTarget(GrContext* gr, const SkImageInfo& info,
+                                             int sampleCount, const SkSurfaceProps* props) {
+        return NewRenderTarget(gr, kYes_Budgeted, info, sampleCount, props);
+    }
 
-    static SkSurface* NewScratchRenderTarget(GrContext* gr, const SkImageInfo& info) {
-        return NewScratchRenderTarget(gr, info, 0, NULL);
+    /**
+     * Deprecated - use the version that takes a Budgeted param.
+     */
+    static SkSurface* NewRenderTarget(GrContext* gr, const SkImageInfo& info, int sampleCount,
+                                      const SkSurfaceProps* props) {
+        return NewRenderTarget(gr, kNo_Budgeted, info, sampleCount, props);
     }
 
     int width() const { return fWidth; }
diff --git a/include/gpu/GrGpuResource.h b/include/gpu/GrGpuResource.h
index 44c4ba0..750ec6a 100644
--- a/include/gpu/GrGpuResource.h
+++ b/include/gpu/GrGpuResource.h
@@ -262,6 +262,7 @@
     bool setContentKey(const GrResourceKey& contentKey);
     void notifyIsPurgable() const;
     void removeScratchKey();
+    void makeBudgeted();
 
 #ifdef SK_DEBUG
     friend class GrGpu; // for assert in GrGpu to access getGpu
diff --git a/src/gpu/GrGpuResource.cpp b/src/gpu/GrGpuResource.cpp
index a2df7e1..2f267a4 100644
--- a/src/gpu/GrGpuResource.cpp
+++ b/src/gpu/GrGpuResource.cpp
@@ -6,7 +6,6 @@
  * found in the LICENSE file.
  */
 
-
 #include "GrGpuResource.h"
 #include "GrResourceCache2.h"
 #include "GrGpu.h"
@@ -134,6 +133,13 @@
     }
 }
 
+void GrGpuResource::makeBudgeted() {
+    if (GrGpuResource::kUncached_LifeCycle == fLifeCycle) {
+        fLifeCycle = kCached_LifeCycle;
+        get_resource_cache2(fGpu)->resourceAccess().didChangeBudgetStatus(this);
+    }
+}
+
 uint32_t GrGpuResource::CreateUniqueID() {
     static int32_t gUniqueID = SK_InvalidUniqueID;
     uint32_t id;
diff --git a/src/gpu/GrGpuResourceCacheAccess.h b/src/gpu/GrGpuResourceCacheAccess.h
index 0aadb89..d7c5028 100644
--- a/src/gpu/GrGpuResourceCacheAccess.h
+++ b/src/gpu/GrGpuResourceCacheAccess.h
@@ -70,6 +70,12 @@
     bool isBudgeted() const { return GrGpuResource::kCached_LifeCycle == fResource->fLifeCycle; }
 
     /**
+     * If the resource is uncached make it cached. Has no effect on resources that are wrapped or
+     * already cached.
+     */
+    void makeBudgeted() { fResource->makeBudgeted(); }
+
+    /**
      * Called by the cache to delete the resource under normal circumstances.
      */
     void release() {
diff --git a/src/gpu/GrResourceCache2.cpp b/src/gpu/GrResourceCache2.cpp
index e23f968..ba9d4d1 100644
--- a/src/gpu/GrResourceCache2.cpp
+++ b/src/gpu/GrResourceCache2.cpp
@@ -306,6 +306,10 @@
     if (resource->cacheAccess().isBudgeted()) {
         ++fBudgetedCount;
         fBudgetedBytes += size;
+#if GR_CACHE_STATS
+        fBudgetedHighWaterBytes = SkTMax(fBudgetedBytes, fBudgetedHighWaterBytes);
+        fBudgetedHighWaterCount = SkTMax(fBudgetedCount, fBudgetedHighWaterCount);
+#endif
         this->purgeAsNeeded();
     } else {
         --fBudgetedCount;
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index 5f47132..e25cba5 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -48,8 +48,6 @@
 
 enum { kDefaultImageFilterCacheSize = 32 * 1024 * 1024 };
 
-#define CACHE_COMPATIBLE_DEVICE_TEXTURES 1
-
 #if 0
     extern bool (*gShouldDrawProc)();
     #define CHECK_SHOULD_DRAW(draw)                             \
@@ -68,8 +66,8 @@
 
 #define DO_DEFERRED_CLEAR()             \
     do {                                \
-        if (fFlags & kNeedClear_Flag) {  \
-            this->clearAll(); \
+        if (fNeedClear) {               \
+            this->clearAll();           \
         }                               \
     } while (false)                     \
 
@@ -124,56 +122,71 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-SkGpuDevice* SkGpuDevice::Create(GrSurface* surface, const SkSurfaceProps& props, unsigned flags) {
-    SkASSERT(surface);
-    if (NULL == surface->asRenderTarget() || surface->wasDestroyed()) {
+SkGpuDevice* SkGpuDevice::Create(GrRenderTarget* rt, const SkSurfaceProps* props, unsigned flags) {
+    if (!rt || rt->wasDestroyed()) {
         return NULL;
     }
-    return SkNEW_ARGS(SkGpuDevice, (surface, props, flags));
+    return SkNEW_ARGS(SkGpuDevice, (rt, props, flags));
 }
 
-static SkDeviceProperties surfaceprops_to_deviceprops(const SkSurfaceProps& props) {
-    return SkDeviceProperties(props.pixelGeometry());
+static SkDeviceProperties surfaceprops_to_deviceprops(const SkSurfaceProps* props) {
+    if (props) {
+        return SkDeviceProperties(props->pixelGeometry());
+    } else {
+        return SkDeviceProperties(SkDeviceProperties::kLegacyLCD_InitType);
+    }
 }
 
-SkGpuDevice::SkGpuDevice(GrSurface* surface, const SkSurfaceProps& props, unsigned flags)
+static SkSurfaceProps copy_or_default_props(const SkSurfaceProps* props) {
+    if (props) {
+        return SkSurfaceProps(*props);
+    } else {
+        return SkSurfaceProps(SkSurfaceProps::kLegacyFontHost_InitType);
+    }
+}
+
+SkGpuDevice::SkGpuDevice(GrRenderTarget* rt, const SkSurfaceProps* props, unsigned flags)
     : INHERITED(surfaceprops_to_deviceprops(props))
+    , fSurfaceProps(copy_or_default_props(props))
 {
     fDrawProcs = NULL;
 
-    fContext = SkRef(surface->getContext());
+    fContext = SkRef(rt->getContext());
+    fNeedClear = flags & kNeedClear_Flag;
 
-    fFlags = flags;
+    fRenderTarget = SkRef(rt);
 
-    fRenderTarget = SkRef(surface->asRenderTarget());
-
-    SkImageInfo info = surface->surfacePriv().info();
-    SkPixelRef* pr = SkNEW_ARGS(SkGrPixelRef, (info, surface));
+    SkImageInfo info = rt->surfacePriv().info();
+    SkPixelRef* pr = SkNEW_ARGS(SkGrPixelRef, (info, rt));
     fLegacyBitmap.setInfo(info);
     fLegacyBitmap.setPixelRef(pr)->unref();
 
-    bool useDFT = SkToBool(flags & kDFText_Flag);
+    bool useDFT = fSurfaceProps.isUseDistanceFieldFonts();
     fTextContext = fContext->createTextContext(fRenderTarget, this->getLeakyProperties(), useDFT);
 }
 
-SkGpuDevice* SkGpuDevice::Create(GrContext* context, const SkImageInfo& origInfo,
-                                 const SkSurfaceProps& props, int sampleCount) {
+SkGpuDevice* SkGpuDevice::Create(GrContext* context, SkSurface::Budgeted budgeted,
+                                 const SkImageInfo& origInfo, int sampleCount,
+                                 const SkSurfaceProps* props, unsigned flags) {
     if (kUnknown_SkColorType == origInfo.colorType() ||
         origInfo.width() < 0 || origInfo.height() < 0) {
         return NULL;
     }
 
+    if (!context) {
+        return NULL;
+    }
+
     SkColorType ct = origInfo.colorType();
     SkAlphaType at = origInfo.alphaType();
-    // TODO: perhaps we can loosen this check now that colortype is more detailed
-    // e.g. can we support both RGBA and BGRA here?
     if (kRGB_565_SkColorType == ct) {
         at = kOpaque_SkAlphaType;  // force this setting
-    } else {
+    } else if (ct != kBGRA_8888_SkColorType && ct != kRGBA_8888_SkColorType) {
+        // Fall back from whatever ct was to default of kRGBA or kBGRA which is aliased as kN32
         ct = kN32_SkColorType;
-        if (kOpaque_SkAlphaType != at) {
-            at = kPremul_SkAlphaType;  // force this setting
-        }
+    }
+    if (kOpaque_SkAlphaType != at) {
+        at = kPremul_SkAlphaType;  // force this setting
     }
     const SkImageInfo info = SkImageInfo::Make(origInfo.width(), origInfo.height(), ct, at);
 
@@ -184,12 +197,18 @@
     desc.fConfig = SkImageInfo2GrPixelConfig(info);
     desc.fSampleCnt = sampleCount;
 
-    SkAutoTUnref<GrTexture> texture(context->createUncachedTexture(desc, NULL, 0));
-    if (!texture.get()) {
+    SkAutoTUnref<GrTexture> texture;
+    if (SkSurface::kYes_Budgeted == budgeted) {
+        texture.reset(context->refScratchTexture(desc, GrContext::kExact_ScratchTexMatch));
+    } else {
+        texture.reset(context->createUncachedTexture(desc, NULL, 0));
+    }
+
+    if (!texture) {
         return NULL;
     }
 
-    return SkNEW_ARGS(SkGpuDevice, (texture.get(), props));
+    return SkNEW_ARGS(SkGpuDevice, (texture->asRenderTarget(), props, flags));
 }
 
 SkGpuDevice::~SkGpuDevice() {
@@ -295,7 +314,7 @@
     GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice::clearAll", fContext);
     SkIRect rect = SkIRect::MakeWH(this->width(), this->height());
     fContext->clear(&rect, color, true, fRenderTarget);
-    fFlags &= ~kNeedClear_Flag;
+    fNeedClear = false;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -1517,7 +1536,7 @@
     // clear of the source device must occur before CHECK_SHOULD_DRAW
     GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice::drawDevice", fContext);
     SkGpuDevice* dev = static_cast<SkGpuDevice*>(device);
-    if (dev->fFlags & kNeedClear_Flag) {
+    if (fNeedClear) {
         // TODO: could check here whether we really need to draw at all
         dev->clearAll();
     }
@@ -1800,21 +1819,17 @@
     SkAutoTUnref<GrTexture> texture;
     // Skia's convention is to only clear a device if it is non-opaque.
     unsigned flags = cinfo.fInfo.isOpaque() ? 0 : kNeedClear_Flag;
-    // If we're using distance field text, enable in the new device
-    flags |= (fFlags & kDFText_Flag) ? kDFText_Flag : 0;
 
-#if CACHE_COMPATIBLE_DEVICE_TEXTURES
     // layers are never draw in repeat modes, so we can request an approx
     // match and ignore any padding.
     const GrContext::ScratchTexMatch match = (kSaveLayer_Usage == cinfo.fUsage) ?
                                                 GrContext::kApprox_ScratchTexMatch :
                                                 GrContext::kExact_ScratchTexMatch;
     texture.reset(fContext->refScratchTexture(desc, match));
-#else
-    texture.reset(fContext->createUncachedTexture(desc, NULL, 0));
-#endif
-    if (texture.get()) {
-        return SkGpuDevice::Create(texture, SkSurfaceProps(0, cinfo.fPixelGeometry), flags);
+
+    if (texture) {
+        SkSurfaceProps props(fSurfaceProps.flags(), cinfo.fPixelGeometry);
+        return SkGpuDevice::Create(texture->asRenderTarget(), &props, flags);
     } else {
         SkDebugf("---- failed to create compatible device texture [%d %d]\n",
                  cinfo.fInfo.width(), cinfo.fInfo.height());
@@ -1823,7 +1838,10 @@
 }
 
 SkSurface* SkGpuDevice::newSurface(const SkImageInfo& info, const SkSurfaceProps& props) {
-    return SkSurface::NewRenderTarget(fContext, info, fRenderTarget->numSamples(), &props);
+    // TODO: Change the signature of newSurface to take a budgeted parameter.
+    static const SkSurface::Budgeted kBudgeted = SkSurface::kNo_Budgeted;
+    return SkSurface::NewRenderTarget(fContext, kBudgeted, info, fRenderTarget->numSamples(),
+                                      &props);
 }
 
 bool SkGpuDevice::EXPERIMENTAL_drawPicture(SkCanvas* mainCanvas, const SkPicture* mainPicture,
diff --git a/src/gpu/SkGpuDevice.h b/src/gpu/SkGpuDevice.h
index 56dad1b..6cbf628 100644
--- a/src/gpu/SkGpuDevice.h
+++ b/src/gpu/SkGpuDevice.h
@@ -6,8 +6,6 @@
  * found in the LICENSE file.
  */
 
-
-
 #ifndef SkGpuDevice_DEFINED
 #define SkGpuDevice_DEFINED
 
@@ -16,6 +14,7 @@
 #include "SkDevice.h"
 #include "SkPicture.h"
 #include "SkRegion.h"
+#include "SkSurface.h"
 #include "GrContext.h"
 #include "GrSurfacePriv.h"
 
@@ -34,25 +33,20 @@
 public:
     enum Flags {
         kNeedClear_Flag = 1 << 0,  //!< Surface requires an initial clear
-        kDFText_Flag   = 1 << 1,  //!< Surface should render text using signed distance fields
     };
 
     /**
-     * Creates an SkGpuDevice from a GrSurface. This will fail if the surface is not a render
-     * target. The caller owns a ref on the returned device. If the surface is cached,
-     * the kCached_Flag should be specified to make the device responsible for unlocking
-     * the surface when it is released.
+     * Creates an SkGpuDevice from a GrRenderTarget.
      */
-    static SkGpuDevice* Create(GrSurface* surface, const SkSurfaceProps&, unsigned flags = 0);
+    static SkGpuDevice* Create(GrRenderTarget* target, const SkSurfaceProps*, unsigned flags = 0);
 
     /**
-     *  New device that will create an offscreen renderTarget based on the
-     *  ImageInfo and sampleCount. The device's storage will not
-     *  count against the GrContext's texture cache budget. The device's pixels
-     *  will be uninitialized. On failure, returns NULL.
+     * New device that will create an offscreen renderTarget based on the ImageInfo and
+     * sampleCount. The Budgeted param controls whether the device's backing store counts against
+     * the resource cache budget. On failure, returns NULL.
      */
-    static SkGpuDevice* Create(GrContext*, const SkImageInfo&, const SkSurfaceProps&,
-                               int sampleCount);
+    static SkGpuDevice* Create(GrContext*, SkSurface::Budgeted, const SkImageInfo&,
+                               int sampleCount, const SkSurfaceProps*, unsigned flags = 0);
 
     virtual ~SkGpuDevice();
 
@@ -63,7 +57,7 @@
         return static_cast<SkGpuDevice*>(dev);
     }
 
-    GrContext* context() const { return fContext; }
+    GrContext* context() const { return fRenderTarget->getContext(); }
 
     // set all pixels to 0
     void clearAll();
@@ -74,6 +68,8 @@
         return fRenderTarget ? fRenderTarget->surfacePriv().info() : SkImageInfo::MakeUnknown();
     }
 
+    const SkSurfaceProps& surfaceProps() const { return fSurfaceProps; }
+
     void drawPaint(const SkDraw&, const SkPaint& paint) SK_OVERRIDE;
     virtual void drawPoints(const SkDraw&, SkCanvas::PointMode mode, size_t count,
                             const SkPoint[], const SkPaint& paint) SK_OVERRIDE;
@@ -139,21 +135,16 @@
 
 private:
     GrContext*      fContext;
-
     GrSkDrawProcs*  fDrawProcs;
-
     GrClipData      fClipData;
-
     GrTextContext*  fTextContext;
-
-    // state for our render-target
+    SkSurfaceProps  fSurfaceProps;
     GrRenderTarget* fRenderTarget;
-    uint32_t        fFlags;
-
     // remove when our clients don't rely on accessBitmap()
-    SkBitmap fLegacyBitmap;
+    SkBitmap        fLegacyBitmap;
+    bool            fNeedClear;
 
-    SkGpuDevice(GrSurface*, const SkSurfaceProps&, unsigned flags = 0);
+    SkGpuDevice(GrRenderTarget*, const SkSurfaceProps*, unsigned flags);
 
     SkBaseDevice* onCreateCompatibleDevice(const CreateInfo&) SK_OVERRIDE;
 
diff --git a/src/image/SkImage_Gpu.cpp b/src/image/SkImage_Gpu.cpp
index 6a42ece..350a1e8 100644
--- a/src/image/SkImage_Gpu.cpp
+++ b/src/image/SkImage_Gpu.cpp
@@ -69,7 +69,9 @@
 
 SkSurface* SkImage_Gpu::onNewSurface(const SkImageInfo& info, const SkSurfaceProps& props) const {
     GrContext* ctx = this->getTexture()->getContext();
-    return SkSurface::NewRenderTarget(ctx, info, fSampleCountForNewSurfaces, &props);
+    // TODO: Change signature of onNewSurface to take a budgeted param.
+    static const SkSurface::Budgeted kBudgeted = SkSurface::kNo_Budgeted;
+    return SkSurface::NewRenderTarget(ctx, kBudgeted, info, fSampleCountForNewSurfaces, &props);
 }
 
 GrTexture* SkImage_Gpu::onGetTexture() const {
diff --git a/src/image/SkSurface.cpp b/src/image/SkSurface.cpp
index 6fd40c1..81b348f 100644
--- a/src/image/SkSurface.cpp
+++ b/src/image/SkSurface.cpp
@@ -183,13 +183,10 @@
     return NULL;
 }
 
-SkSurface* SkSurface::NewRenderTarget(GrContext*, const SkImageInfo&, int, const SkSurfaceProps*) {
+SkSurface* SkSurface::NewRenderTarget(GrContext*, Budgeted, const SkImageInfo&, int,
+                                      const SkSurfaceProps*) {
     return NULL;
 }
 
-SkSurface* SkSurface::NewScratchRenderTarget(GrContext*, const SkImageInfo&, int sampleCount,
-                                             const SkSurfaceProps*) {
-    return NULL;
-}
 
 #endif
diff --git a/src/image/SkSurface_Gpu.cpp b/src/image/SkSurface_Gpu.cpp
index e58375b..6cd741d 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 @@
 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 @@
     // 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 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 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
diff --git a/src/image/SkSurface_Gpu.h b/src/image/SkSurface_Gpu.h
index 4a49272..f87c5d7 100644
--- a/src/image/SkSurface_Gpu.h
+++ b/src/image/SkSurface_Gpu.h
@@ -18,7 +18,7 @@
 public:
     SK_DECLARE_INST_COUNT(SkSurface_Gpu)
 
-    SkSurface_Gpu(GrRenderTarget*, const SkSurfaceProps*, bool doClear);
+    SkSurface_Gpu(SkGpuDevice*);
     virtual ~SkSurface_Gpu();
 
     SkCanvas* onNewCanvas() SK_OVERRIDE;
diff --git a/tests/DeferredCanvasTest.cpp b/tests/DeferredCanvasTest.cpp
index 4ec67ae..3089dc0 100644
--- a/tests/DeferredCanvasTest.cpp
+++ b/tests/DeferredCanvasTest.cpp
@@ -698,7 +698,8 @@
                 return;
             }
 
-            surface = SkSurface::NewRenderTarget(context, imageSpec, 0, NULL);
+            surface =
+                SkSurface::NewRenderTarget(context, SkSurface::kNo_Budgeted, imageSpec, 0, NULL);
         } else
 #endif
         {
@@ -780,8 +781,10 @@
             if (NULL == context) {
                 continue;
             }
-            surface = SkSurface::NewRenderTarget(context, imageSpec, 0, NULL);
-            alternateSurface = SkSurface::NewRenderTarget(context, imageSpec, 0, NULL);
+            surface =
+                SkSurface::NewRenderTarget(context, SkSurface::kNo_Budgeted, imageSpec, 0, NULL);
+            alternateSurface =
+                SkSurface::NewRenderTarget(context, SkSurface::kNo_Budgeted, imageSpec, 0, NULL);
         } else
 #endif
         {
diff --git a/tests/GpuDrawPathTest.cpp b/tests/GpuDrawPathTest.cpp
index 3e47a05..b86689f 100644
--- a/tests/GpuDrawPathTest.cpp
+++ b/tests/GpuDrawPathTest.cpp
@@ -56,8 +56,9 @@
         for (size_t i = 0; i < SK_ARRAY_COUNT(sampleCounts); ++i) {
             SkImageInfo info = SkImageInfo::MakeN32Premul(255, 255);
             
-            SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTarget(grContext, info,
-                                                                       sampleCounts[i], NULL));
+            SkAutoTUnref<SkSurface> surface(
+                SkSurface::NewRenderTarget(grContext, SkSurface::kNo_Budgeted, info,
+                                           sampleCounts[i], NULL));
             test_drawPathEmpty(reporter, surface->getCanvas());
         }
     }
diff --git a/tests/ImageFilterTest.cpp b/tests/ImageFilterTest.cpp
index 4ffcc11..55499d7 100644
--- a/tests/ImageFilterTest.cpp
+++ b/tests/ImageFilterTest.cpp
@@ -1074,36 +1074,40 @@
 DEF_GPUTEST(ImageFilterCropRectGPU, reporter, factory) {
     GrContext* context = factory->get(static_cast<GrContextFactory::GLContextType>(0));
     SkAutoTUnref<SkGpuDevice> device(SkGpuDevice::Create(context,
+                                                         SkSurface::kNo_Budgeted,
                                                          SkImageInfo::MakeN32Premul(100, 100),
-                                                         gProps,
-                                                         0));
+                                                         0,
+                                                         &gProps));
     test_crop_rects(device, reporter);
 }
 
 DEF_GPUTEST(HugeBlurImageFilterGPU, reporter, factory) {
     GrContext* context = factory->get(static_cast<GrContextFactory::GLContextType>(0));
     SkAutoTUnref<SkGpuDevice> device(SkGpuDevice::Create(context,
+                                                         SkSurface::kNo_Budgeted,
                                                          SkImageInfo::MakeN32Premul(100, 100),
-                                                         gProps,
-                                                         0));
+                                                         0,
+                                                         &gProps));
     test_huge_blur(device, reporter);
 }
 
 DEF_GPUTEST(XfermodeImageFilterCroppedInputGPU, reporter, factory) {
     GrContext* context = factory->get(static_cast<GrContextFactory::GLContextType>(0));
     SkAutoTUnref<SkGpuDevice> device(SkGpuDevice::Create(context,
+                                                         SkSurface::kNo_Budgeted,
                                                          SkImageInfo::MakeN32Premul(1, 1),
-                                                         gProps,
-                                                         0));
+                                                         0,
+                                                         &gProps));
     test_xfermode_cropped_input(device, reporter);
 }
 
 DEF_GPUTEST(TestNegativeBlurSigmaGPU, reporter, factory) {
     GrContext* context = factory->get(static_cast<GrContextFactory::GLContextType>(0));
     SkAutoTUnref<SkGpuDevice> device(SkGpuDevice::Create(context,
+                                                         SkSurface::kNo_Budgeted,
                                                          SkImageInfo::MakeN32Premul(1, 1),
-                                                         gProps,
-                                                         0));
+                                                         0,
+                                                         &gProps));
     test_negative_blur_sigma(device, reporter);
 }
 #endif
diff --git a/tests/ImageIsOpaqueTest.cpp b/tests/ImageIsOpaqueTest.cpp
index 6d886d4..522bd94 100644
--- a/tests/ImageIsOpaqueTest.cpp
+++ b/tests/ImageIsOpaqueTest.cpp
@@ -80,11 +80,13 @@
         }
 
         SkImageInfo infoTransparent = SkImageInfo::MakeN32Premul(5, 5);
-        SkAutoTUnref<SkSurface> surfaceTransparent(SkSurface::NewRenderTarget(context, infoTransparent));
+        SkAutoTUnref<SkSurface> surfaceTransparent(
+            SkSurface::NewRenderTarget(context,SkSurface::kNo_Budgeted, infoTransparent));
         check_isopaque(reporter, surfaceTransparent, false);
 
         SkImageInfo infoOpaque = SkImageInfo::MakeN32(5, 5, kOpaque_SkAlphaType);
-        SkAutoTUnref<SkSurface> surfaceOpaque(SkSurface::NewRenderTarget(context, infoOpaque));
+        SkAutoTUnref<SkSurface> surfaceOpaque(
+            SkSurface::NewRenderTarget(context,SkSurface::kNo_Budgeted, infoOpaque));
 #if 0
         // this is failing right now : TODO fix me
         check_isopaque(reporter, surfaceOpaque, true);
diff --git a/tests/ImageNewShaderTest.cpp b/tests/ImageNewShaderTest.cpp
index 1bc77fb..c78b715 100644
--- a/tests/ImageNewShaderTest.cpp
+++ b/tests/ImageNewShaderTest.cpp
@@ -115,8 +115,10 @@
 void gpuToGpu(skiatest::Reporter* reporter, GrContext* context) {
     SkImageInfo info = SkImageInfo::MakeN32Premul(5, 5);
 
-    SkAutoTUnref<SkSurface> sourceSurface(SkSurface::NewRenderTarget(context, info));
-    SkAutoTUnref<SkSurface> destinationSurface(SkSurface::NewRenderTarget(context, info));
+    SkAutoTUnref<SkSurface> sourceSurface(
+        SkSurface::NewRenderTarget(context, SkSurface::kNo_Budgeted, info));
+    SkAutoTUnref<SkSurface> destinationSurface(
+        SkSurface::NewRenderTarget(context, SkSurface::kNo_Budgeted, info));
 
     runShaderTest(reporter, sourceSurface.get(), destinationSurface.get(), info);
 }
@@ -124,7 +126,8 @@
 void gpuToRaster(skiatest::Reporter* reporter, GrContext* context) {
     SkImageInfo info = SkImageInfo::MakeN32Premul(5, 5);
 
-    SkAutoTUnref<SkSurface> sourceSurface(SkSurface::NewRenderTarget(context, info));
+    SkAutoTUnref<SkSurface> sourceSurface(SkSurface::NewRenderTarget(context,
+        SkSurface::kNo_Budgeted, info));
     SkAutoTUnref<SkSurface> destinationSurface(SkSurface::NewRaster(info));
 
     runShaderTest(reporter, sourceSurface.get(), destinationSurface.get(), info);
@@ -134,7 +137,8 @@
     SkImageInfo info = SkImageInfo::MakeN32Premul(5, 5);
 
     SkAutoTUnref<SkSurface> sourceSurface(SkSurface::NewRaster(info));
-    SkAutoTUnref<SkSurface> destinationSurface(SkSurface::NewRenderTarget(context, info));
+    SkAutoTUnref<SkSurface> destinationSurface(SkSurface::NewRenderTarget(context,
+        SkSurface::kNo_Budgeted, info));
 
     runShaderTest(reporter, sourceSurface.get(), destinationSurface.get(), info);
 }
diff --git a/tests/PremulAlphaRoundTripTest.cpp b/tests/PremulAlphaRoundTripTest.cpp
index ce45f16..9f5d6ff 100644
--- a/tests/PremulAlphaRoundTripTest.cpp
+++ b/tests/PremulAlphaRoundTripTest.cpp
@@ -85,13 +85,12 @@
                 if (!GrContextFactory::IsRenderingGLContext(type)) {
                     continue;
                 }
-                GrContext* context = factory->get(type);
-                if (NULL == context) {
+                GrContext* ctx = factory->get(type);
+                if (NULL == ctx) {
                     continue;
                 }
-
-                device.reset(SkGpuDevice::Create(context, info,
-                                     SkSurfaceProps(SkSurfaceProps::kLegacyFontHost_InitType), 0));
+                SkSurfaceProps props(SkSurfaceProps::kLegacyFontHost_InitType);
+                device.reset(SkGpuDevice::Create(ctx, SkSurface::kNo_Budgeted, info, 0, &props));
 #else
                 continue;
 #endif
diff --git a/tests/ReadWriteAlphaTest.cpp b/tests/ReadWriteAlphaTest.cpp
index 6bcc51f..966bc7f 100644
--- a/tests/ReadWriteAlphaTest.cpp
+++ b/tests/ReadWriteAlphaTest.cpp
@@ -82,8 +82,8 @@
         REPORTER_ASSERT(reporter, match);
 
         // Now try writing on the single channel texture
-        SkAutoTUnref<SkBaseDevice> device(SkGpuDevice::Create(texture->asRenderTarget(),
-                                      SkSurfaceProps(SkSurfaceProps::kLegacyFontHost_InitType)));
+        SkSurfaceProps props(SkSurfaceProps::kLegacyFontHost_InitType);
+        SkAutoTUnref<SkBaseDevice> device(SkGpuDevice::Create(texture->asRenderTarget(), &props));
         SkCanvas canvas(device);
 
         SkPaint paint;
diff --git a/tests/ResourceCacheTest.cpp b/tests/ResourceCacheTest.cpp
index 8639626..e51b3e0 100644
--- a/tests/ResourceCacheTest.cpp
+++ b/tests/ResourceCacheTest.cpp
@@ -797,7 +797,8 @@
         desc.fWidth = gWidth;
         desc.fHeight = gHeight;
         SkImageInfo info = SkImageInfo::MakeN32Premul(gWidth, gHeight);
-        SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTarget(context, info));
+        SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTarget(context,
+                                                                   SkSurface::kNo_Budgeted, info));
         test_cache(reporter, context, surface->getCanvas());
     }
 
diff --git a/tests/SurfaceTest.cpp b/tests/SurfaceTest.cpp
index c09d97c..4816ffc 100644
--- a/tests/SurfaceTest.cpp
+++ b/tests/SurfaceTest.cpp
@@ -50,15 +50,9 @@
                                                          release_storage, storage);
         }
         case kGpu_SurfaceType:
-#if SK_SUPPORT_GPU
-            return context ? SkSurface::NewRenderTarget(context, info, 0, NULL) : NULL;
-#endif
-            break;
+            return SkSurface::NewRenderTarget(context, SkSurface::kNo_Budgeted, info, 0, NULL);
         case kGpuScratch_SurfaceType:
-#if SK_SUPPORT_GPU
-            return context ? SkSurface::NewScratchRenderTarget(context, info) : NULL;
-#endif
-            break;
+            return SkSurface::NewRenderTarget(context, SkSurface::kYes_Budgeted, info, 0, NULL);
     }
     return NULL;
 }
@@ -94,8 +88,8 @@
     REPORTER_ASSERT(reporter, NULL == SkSurface::NewRaster(info));
     REPORTER_ASSERT(reporter, NULL == SkSurface::NewRasterDirect(info, NULL, 0));
     if (ctx) {
-        REPORTER_ASSERT(reporter, NULL == SkSurface::NewRenderTarget(ctx, info, 0, NULL));
-        REPORTER_ASSERT(reporter, NULL == SkSurface::NewScratchRenderTarget(ctx, info, 0, NULL));
+        REPORTER_ASSERT(reporter, NULL ==
+                        SkSurface::NewRenderTarget(ctx, SkSurface::kNo_Budgeted, info, 0, NULL));
     }
 }
 
@@ -129,7 +123,8 @@
         case kRasterData_ImageType:
             return SkImage::NewRasterData(info, data, rowBytes);
         case kGpu_ImageType: {
-            SkAutoTUnref<SkSurface> surf(SkSurface::NewRenderTarget(context, info, 0));
+            SkAutoTUnref<SkSurface> surf(
+                SkSurface::NewRenderTarget(context, SkSurface::kNo_Budgeted, info, 0));
             surf->getCanvas()->clear(color);
             return surf->newImageSnapshot();
         }
diff --git a/tools/PictureRenderer.cpp b/tools/PictureRenderer.cpp
index 0d7e14c..dc672f0 100644
--- a/tools/PictureRenderer.cpp
+++ b/tools/PictureRenderer.cpp
@@ -157,16 +157,14 @@
                 desc.fSampleCnt = fSampleCount;
                 target.reset(fGrContext->createUncachedTexture(desc, NULL, 0));
             }
-            if (NULL == target.get()) {
-                SkASSERT(0);
+
+            uint32_t flags = fUseDFText ? SkSurfaceProps::kUseDistanceFieldFonts_Flag : 0;
+            SkSurfaceProps props(flags, SkSurfaceProps::kLegacyFontHost_InitType);
+            SkAutoTUnref<SkGpuDevice> device(SkGpuDevice::Create(target->asRenderTarget(), &props));
+            if (!device) {
                 return NULL;
             }
-
-            uint32_t flags = fUseDFText ? SkGpuDevice::kDFText_Flag : 0;
-            SkAutoTUnref<SkGpuDevice> device(SkGpuDevice::Create(target,
-                                         SkSurfaceProps(SkSurfaceProps::kLegacyFontHost_InitType),
-                                         flags));
-            canvas = SkNEW_ARGS(SkCanvas, (device.get()));
+            canvas = SkNEW_ARGS(SkCanvas, (device));
             break;
         }
 #endif