Add createNewCompatibleDevice. Allow devices to have a NULL factory and saveLayer will fall back on createNewCompatibleDevice.

Review URL: http://codereview.appspot.com/4633044/



git-svn-id: http://skia.googlecode.com/svn/trunk@1625 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index 189b692..cda10d2 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -76,7 +76,7 @@
         fTex = NULL;
     } else {
         // look it up in our cache
-        fTex = device->lockCachedTexture(bitmap, sampler, &texture, false);
+        fTex = device->lockCachedTexture(bitmap, sampler, &texture);
     }
     return texture;
 }
@@ -166,7 +166,7 @@
 }
 
 SkGpuDevice::SkGpuDevice(GrContext* context, SkBitmap::Config config, int width,
-                         int height, bool isForSaveLayer)
+                         int height, Usage usage)
 : SkDevice(config, width, height, false /*isOpaque*/) {
     fNeedPrepareRenderTarget = false;
     fDrawProcs = NULL;
@@ -186,9 +186,11 @@
     bm.setConfig(config, width, height);
 
 #if CACHE_LAYER_TEXTURES
-
+    TexType type = (kSaveLayer_Usage == usage) ? 
+                            kSaveLayerDeviceRenderTarget_TexType :
+                            kDeviceRenderTarget_TexType;
     fCache = this->lockCachedTexture(bm, GrSamplerState::ClampNoFilter(),
-                                     &fTexture, true, isForSaveLayer);
+                                     &fTexture, type);
     if (fCache) {
         SkASSERT(NULL != fTexture);
         SkASSERT(NULL != fTexture->asRenderTarget());
@@ -1394,13 +1396,12 @@
 SkGpuDevice::TexCache* SkGpuDevice::lockCachedTexture(const SkBitmap& bitmap,
                                                       const GrSamplerState& sampler,
                                                       GrTexture** texture,
-                                                      bool forDeviceRenderTarget,
-                                                      bool isSaveLayer) {
+                                                      TexType type) {
     GrTexture* newTexture = NULL;
     GrTextureEntry* entry = NULL;
     GrContext* ctx = this->context();
 
-    if (forDeviceRenderTarget) {
+    if (kBitmap_TexType != type) {
         const GrTextureDesc desc = {
             kRenderTarget_GrTextureFlagBit,
             kNone_GrAALevel,
@@ -1408,12 +1409,13 @@
             bitmap.height(),
             SkGr::Bitmap2PixelConfig(bitmap)
         };
-        if (isSaveLayer) {
+        if (kSaveLayerDeviceRenderTarget_TexType == type) {
             // we know layers will only be drawn through drawDevice.
             // drawDevice has been made to work with content embedded in a
             // larger texture so its okay to use the approximate version.
             entry = ctx->findApproximateKeylessTexture(desc);
         } else {
+            SkASSERT(kDeviceRenderTarget_TexType == type);
             entry = ctx->lockKeylessTexture(desc);
         }
     } else {
@@ -1446,6 +1448,15 @@
     this->context()->unlockTexture((GrTextureEntry*)cache);
 }
 
+SkDevice* SkGpuDevice::onCreateCompatibleDevice(SkBitmap::Config config, 
+                                                int width, int height, 
+                                                bool isOpaque,
+                                                Usage usage) {
+    return SkNEW_ARGS(SkGpuDevice,(this->context(), config, 
+                                   width, height, usage));
+}
+
+
 ///////////////////////////////////////////////////////////////////////////////
 
 SkGpuDeviceFactory::SkGpuDeviceFactory(GrContext* context,
@@ -1499,3 +1510,4 @@
         return SkNEW_ARGS(SkGpuDevice, (fContext, fRootRenderTarget));
     }
 }
+