Revet 3563 due to mac bot failure
authorbsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Fri, 30 Mar 2012 18:29:01 +0000 (18:29 +0000)
committerbsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Fri, 30 Mar 2012 18:29:01 +0000 (18:29 +0000)
git-svn-id: http://skia.googlecode.com/svn/trunk@3564 2bbb7eff-a529-9590-31e7-b0007b416f81

include/gpu/SkGpuDevice.h
src/gpu/SkGpuDevice.cpp

index ffc24a8..409e3b3 100644 (file)
@@ -29,11 +29,14 @@ class SK_API SkGpuDevice : public SkDevice {
 public:
     /**
      *  New device that will create an offscreen renderTarget based on the
-     *  config, width, height. The device's storage will not count against
-     *  the GrContext's texture cache budget. The device's pixels will be
-     *  uninitialized.
+     *  config, width, height.
+     *
+     *  usage is a special flag that should only be set by SkCanvas
+     *  internally.
      */
-    SkGpuDevice(GrContext*, SkBitmap::Config, int width, int height);
+    SkGpuDevice(GrContext*, SkBitmap::Config,
+                int width, int height,
+                SkDevice::Usage usage = SkDevice::kGeneral_Usage);
 
     /**
      *  New device that will render to the specified renderTarget.
@@ -115,8 +118,14 @@ public:
 
 protected:
     typedef GrContext::TextureCacheEntry TexCache;
+    enum TexType {
+        kBitmap_TexType,
+        kDeviceRenderTarget_TexType,
+        kSaveLayerDeviceRenderTarget_TexType
+    };
     TexCache lockCachedTexture(const SkBitmap& bitmap,
-                               const GrSamplerState* sampler);
+                               const GrSamplerState* sampler,
+                               TexType type = kBitmap_TexType);
     bool isBitmapInTextureCache(const SkBitmap& bitmap,
                                 const GrSamplerState& sampler) const;
     void unlockCachedTexture(TexCache);
@@ -143,9 +152,6 @@ private:
     // called from rt and tex cons
     void initFromRenderTarget(GrContext*, GrRenderTarget*);
 
-    // used by createCompatibleDevice
-    SkGpuDevice(GrContext*, GrTexture* texture, TexCache, bool needClear);
-
     // override from SkDevice
     virtual SkDevice* onCreateCompatibleDevice(SkBitmap::Config config,
                                                int width, int height,
index b4656b9..e13a0ea 100644 (file)
@@ -22,7 +22,7 @@
 #include "SkTLazy.h"
 #include "SkUtils.h"
 
-#define CACHE_COMPATIBLE_DEVICE_TEXTURES 1
+#define CACHE_LAYER_TEXTURES 1
 
 #if 0
     extern bool (*gShouldDrawProc)();
         do {                                                    \
             if (gShouldDrawProc && !gShouldDrawProc()) return;  \
             this->prepareRenderTarget(draw);                    \
-            GrAssert(!fNeedClear)                               \
         } while (0)
 #else
-    #define CHECK_SHOULD_DRAW(draw) this->prepareRenderTarget(draw); \
-                                    GrAssert(!fNeedClear)
+    #define CHECK_SHOULD_DRAW(draw) this->prepareRenderTarget(draw)
 #endif
 
 // we use the same texture slot on GrPaint for bitmaps and shaders
@@ -61,15 +59,6 @@ enum {
 // requiring texture domain clamping to prevent color bleeding when drawing 
 // a sub region of a larger source image.
 #define COLOR_BLEED_TOLERANCE SkFloatToScalar(0.001f)
-
-#define DO_DEFERRED_CLEAR       \
-    do {                        \
-        if (fNeedClear) {       \
-            this->clear(NULL);  \
-            fNeedClear = false; \
-        }                       \
-    } while (false)             \
-
 ///////////////////////////////////////////////////////////////////////////////
 
 class SkGpuDevice::SkAutoCachedTexture : public ::SkNoncopyable {
@@ -204,11 +193,9 @@ void SkGpuDevice::initFromRenderTarget(GrContext* context,
     fTextContext = NULL;
 }
 
-SkGpuDevice::SkGpuDevice(GrContext* context,
-                         SkBitmap::Config config,
-                         int width,
-                         int height)
-    : SkDevice(config, width, height, false /*isOpaque*/) {
+SkGpuDevice::SkGpuDevice(GrContext* context, SkBitmap::Config config, int width,
+                         int height, Usage usage)
+: SkDevice(config, width, height, false /*isOpaque*/) {
     fNeedPrepareRenderTarget = false;
     fDrawProcs = NULL;
 
@@ -225,6 +212,19 @@ SkGpuDevice::SkGpuDevice(GrContext* context,
     SkBitmap bm;
     bm.setConfig(config, width, height);
 
+#if CACHE_LAYER_TEXTURES
+    TexType type = (kSaveLayer_Usage == usage) ?
+                            kSaveLayerDeviceRenderTarget_TexType :
+                            kDeviceRenderTarget_TexType;
+    fCache = this->lockCachedTexture(bm, NULL, type);
+    fTexture = fCache.texture();
+    if (fTexture) {
+        SkASSERT(NULL != fTexture->asRenderTarget());
+        // hold a ref directly on fTexture (even though fCache has one) to match
+        // other constructor paths. Simplifies cleanup.
+        fTexture->ref();
+    }
+#else
     const GrTextureDesc desc = {
         kRenderTarget_GrTextureFlagBit,
         width,
@@ -234,13 +234,16 @@ SkGpuDevice::SkGpuDevice(GrContext* context,
     };
 
     fTexture = fContext->createUncachedTexture(desc, NULL, 0);
-
+#endif
     if (NULL != fTexture) {
         fRenderTarget = fTexture->asRenderTarget();
         fRenderTarget->ref();
 
         GrAssert(NULL != fRenderTarget);
 
+        // we defer the actual clear until our gainFocus()
+        fNeedClear = true;
+
         // wrap the bitmap with a pixelref to expose our texture
         SkGrTexturePixelRef* pr = new SkGrTexturePixelRef(fTexture);
         this->setPixelRef(pr, 0)->unref();
@@ -275,7 +278,6 @@ SkGpuDevice::~SkGpuDevice() {
 ///////////////////////////////////////////////////////////////////////////////
 
 void SkGpuDevice::makeRenderTargetCurrent() {
-    DO_DEFERRED_CLEAR;
     fContext->setRenderTarget(fRenderTarget);
     fContext->flush(true);
     fNeedPrepareRenderTarget = true;
@@ -308,7 +310,6 @@ GrPixelConfig config8888_to_gr_config(SkCanvas::Config8888 config8888) {
 bool SkGpuDevice::onReadPixels(const SkBitmap& bitmap,
                                int x, int y,
                                SkCanvas::Config8888 config8888) {
-    DO_DEFERRED_CLEAR;
     SkASSERT(SkBitmap::kARGB_8888_Config == bitmap.config());
     SkASSERT(!bitmap.isNull());
     SkASSERT(SkIRect::MakeWH(this->width(), this->height()).contains(SkIRect::MakeXYWH(x, y, bitmap.width(), bitmap.height())));
@@ -395,11 +396,13 @@ void SkGpuDevice::gainFocus(SkCanvas* canvas, const SkMatrix& matrix,
 
     convert_matrixclip(fContext, matrix, clipStack, clip, this->getOrigin());
 
-    DO_DEFERRED_CLEAR;
+    if (fNeedClear) {
+        fContext->clear(NULL, 0x0);
+        fNeedClear = false;
+    }
 }
 
 SkGpuRenderTarget* SkGpuDevice::accessRenderTarget() {
-    DO_DEFERRED_CLEAR;
     return (SkGpuRenderTarget*)fRenderTarget;
 }
 
@@ -593,7 +596,6 @@ inline bool skPaint2GrPaintShader(SkGpuDevice* dev,
 ///////////////////////////////////////////////////////////////////////////////
 
 void SkGpuDevice::clear(SkColor color) {
-    fContext->setRenderTarget(fRenderTarget);
     fContext->clear(NULL, color);
 }
 
@@ -1507,19 +1509,12 @@ void SkGpuDevice::drawSprite(const SkDraw& draw, const SkBitmap& bitmap,
                                         GR_Scalar1 * h / texture->height()));
 }
 
-void SkGpuDevice::drawDevice(const SkDraw& draw, SkDevice* device,
+void SkGpuDevice::drawDevice(const SkDraw& draw, SkDevice* dev,
                             int x, int y, const SkPaint& paint) {
-    // clear of the source device must occur before CHECK_SHOULD_DRAW
-    SkGpuDevice* dev = static_cast<SkGpuDevice*>(dev);
-    if (dev->fNeedClear) {
-        // TODO: could check here whether we really need to draw at all
-        dev->clear(0x0);
-    }
-
     CHECK_SHOULD_DRAW(draw);
 
     GrPaint grPaint;
-    if (!dev->bindDeviceAsTexture(&grPaint) ||
+    if (!((SkGpuDevice*)dev)->bindDeviceAsTexture(&grPaint) ||
         !skPaint2GrPaintNoShader(paint, true, false, &grPaint)) {
         return;
     }
@@ -1814,35 +1809,55 @@ bool SkGpuDevice::filterTextFlags(const SkPaint& paint, TextFlags* flags) {
 }
 
 void SkGpuDevice::flush() {
-    DO_DEFERRED_CLEAR;
     fContext->resolveRenderTarget(fRenderTarget);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 
-SkGpuDevice::TexCache SkGpuDevice::lockCachedTexture(
-                                            const SkBitmap& bitmap,
-                                            const GrSamplerState* sampler) {
+SkGpuDevice::TexCache SkGpuDevice::lockCachedTexture(const SkBitmap& bitmap,
+                                            const GrSamplerState* sampler,
+                                            TexType type) {
     GrContext::TextureCacheEntry entry;
     GrContext* ctx = this->context();
 
-    if (!bitmap.isVolatile()) {
-        GrContext::TextureKey key = bitmap.getGenerationID();
-        key |= ((uint64_t) bitmap.pixelRefOffset()) << 32;
-
-        entry = ctx->findAndLockTexture(key, bitmap.width(),
-                                        bitmap.height(), sampler);
-        if (NULL == entry.texture()) {
-            entry = sk_gr_create_bitmap_texture(ctx, key, sampler,
-                                                bitmap);
+    if (kBitmap_TexType != type) {
+        const GrTextureDesc desc = {
+            kRenderTarget_GrTextureFlagBit,
+            bitmap.width(),
+            bitmap.height(),
+            SkGr::Bitmap2PixelConfig(bitmap),
+            0 // samples
+        };
+        GrContext::ScratchTexMatch match;
+        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.
+            match = GrContext::kApprox_ScratchTexMatch;
+        } else {
+            SkASSERT(kDeviceRenderTarget_TexType == type);
+            match = GrContext::kExact_ScratchTexMatch;
         }
+        entry = ctx->lockScratchTexture(desc, match);
     } else {
-        entry = sk_gr_create_bitmap_texture(ctx, gUNCACHED_KEY,
-                                            sampler, bitmap);
-    }
-    if (NULL == entry.texture()) {
-        GrPrintf("---- failed to create texture for cache [%d %d]\n",
-                    bitmap.width(), bitmap.height());
+        if (!bitmap.isVolatile()) {
+            GrContext::TextureKey key = bitmap.getGenerationID();
+            key |= ((uint64_t) bitmap.pixelRefOffset()) << 32;
+
+            entry = ctx->findAndLockTexture(key, bitmap.width(),
+                                            bitmap.height(), sampler);
+            if (NULL == entry.texture()) {
+                entry = sk_gr_create_bitmap_texture(ctx, key, sampler,
+                                                    bitmap);
+            }
+        } else {
+            entry = sk_gr_create_bitmap_texture(ctx, gUNCACHED_KEY,
+                                                sampler, bitmap);
+        }
+        if (NULL == entry.texture()) {
+            GrPrintf("---- failed to create texture for cache [%d %d]\n",
+                     bitmap.width(), bitmap.height());
+        }
     }
     return entry;
 }
@@ -1865,53 +1880,8 @@ SkDevice* SkGpuDevice::onCreateCompatibleDevice(SkBitmap::Config config,
                                                 int width, int height,
                                                 bool isOpaque,
                                                 Usage usage) {
-    GrTextureDesc desc;
-    desc.fConfig = fRenderTarget->config();
-    desc.fFlags = kRenderTarget_GrTextureFlagBit;
-    desc.fWidth = width;
-    desc.fHeight = height;
-    desc.fSampleCnt = fRenderTarget->numSamples();
-
-    GrContext::TextureCacheEntry cacheEntry;
-    GrTexture* texture;
-    SkAutoTUnref<GrTexture> tunref;
-    // Skia's convention is to only clear a device if it is a non-opaque layer.
-    bool needClear = !isOpaque && kSaveLayer_Usage == usage;
-
-#if CACHE_COMPATIBLE_DEVICE_TEXTURES
-    // layers are never draw in repeat modes, so we can request an approx
-    // match and ignore any padding.
-    GrContext::ScratchTexMatch matchType = (kSaveLayer_Usage == usage) ?
-                                    GrContext::kApprox_ScratchTexMatch :
-                                    GrContext::kExact_ScratchTexMatch;
-    cacheEntry = fContext->lockScratchTexture(desc, matchType);
-    texture = cacheEntry.texture();
-#else
-    tunref.reset(fContext->createUncachedTexture(desc, NULL, 0));
-    texture = tunref.get();
-#endif
-    if (texture) {
-        return SkNEW_ARGS(SkGpuDevice,(fContext,
-                                       texture,
-                                       cacheEntry,
-                                       needClear));
-    } else {
-        GrPrintf("---- failed to create compatible device texture [%d %d]\n",
-                    width, height);
-        return NULL;
-    }
-}
-
-SkGpuDevice::SkGpuDevice(GrContext* context,
-                         GrTexture* texture,
-                         TexCache cacheEntry,
-                         bool needClear)
-    : SkDevice(make_bitmap(context, texture->asRenderTarget())) {
-    GrAssert(texture && texture->asRenderTarget());
-    GrAssert(NULL == cacheEntry.texture() || texture == cacheEntry.texture());
-    this->initFromRenderTarget(context, texture->asRenderTarget());
-    fCache = cacheEntry;
-    fNeedClear = needClear;
+    return SkNEW_ARGS(SkGpuDevice,(this->context(), config,
+                                   width, height, usage));
 }
 
 GrTextContext* SkGpuDevice::getTextContext() {