Add a GrLayerCache to GrContext
authorrobertphillips@google.com <robertphillips@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Thu, 3 Apr 2014 00:34:27 +0000 (00:34 +0000)
committerrobertphillips@google.com <robertphillips@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Thu, 3 Apr 2014 00:34:27 +0000 (00:34 +0000)
https://codereview.chromium.org/217343006/

git-svn-id: http://skia.googlecode.com/svn/trunk@14038 2bbb7eff-a529-9590-31e7-b0007b416f81

gyp/gpu.gypi
include/gpu/GrContext.h
src/gpu/GrContext.cpp
src/gpu/GrLayerCache.cpp [new file with mode: 0644]
src/gpu/GrLayerCache.h [new file with mode: 0644]
src/gpu/SkGpuDevice.cpp

index b2f5373..5eb9a79 100644 (file)
@@ -82,6 +82,8 @@
       '<(skia_src_path)/gpu/GrIndexBuffer.h',
       '<(skia_src_path)/gpu/GrInOrderDrawBuffer.cpp',
       '<(skia_src_path)/gpu/GrInOrderDrawBuffer.h',
+      '<(skia_src_path)/gpu/GrLayerCache.cpp',
+      '<(skia_src_path)/gpu/GrLayerCache.h',
       '<(skia_src_path)/gpu/GrMemoryPool.cpp',
       '<(skia_src_path)/gpu/GrMemoryPool.h',
       '<(skia_src_path)/gpu/GrOrderedSet.h',
index e8ce27f..b625389 100644 (file)
@@ -28,6 +28,7 @@ class GrGpu;
 class GrIndexBuffer;
 class GrIndexBufferAllocPool;
 class GrInOrderDrawBuffer;
+class GrLayerCache;
 class GrOvalRenderer;
 class GrPath;
 class GrPathRenderer;
@@ -860,6 +861,7 @@ public:
     GrGpu* getGpu() { return fGpu; }
     const GrGpu* getGpu() const { return fGpu; }
     GrFontCache* getFontCache() { return fFontCache; }
+    GrLayerCache* getLayerCache() { return fLayerCache.get(); }
     GrDrawTarget* getTextTarget();
     const GrIndexBuffer* getQuadIndexBuffer() const;
 
@@ -907,6 +909,7 @@ private:
 
     GrResourceCache*                fTextureCache;
     GrFontCache*                    fFontCache;
+    SkAutoTDelete<GrLayerCache>     fLayerCache;
 
     GrPathRendererChain*            fPathRendererChain;
     GrSoftwarePathRenderer*         fSoftwarePathRenderer;
index c2f62d8..89548ab 100644 (file)
@@ -18,6 +18,7 @@
 #include "GrDrawTargetCaps.h"
 #include "GrIndexBuffer.h"
 #include "GrInOrderDrawBuffer.h"
+#include "GrLayerCache.h"
 #include "GrOvalRenderer.h"
 #include "GrPathRenderer.h"
 #include "GrPathUtils.h"
@@ -124,6 +125,8 @@ bool GrContext::init(GrBackend backend, GrBackendContext backendContext) {
 
     fFontCache = SkNEW_ARGS(GrFontCache, (fGpu));
 
+    fLayerCache.reset(SkNEW_ARGS(GrLayerCache, (fGpu)));
+
     fLastDrawWasBuffered = kNo_BufferedDraw;
 
     fAARectRenderer = SkNEW(GrAARectRenderer);
@@ -197,6 +200,7 @@ void GrContext::contextDestroyed() {
     fTextureCache->purgeAllUnlocked();
 
     fFontCache->freeAll();
+    fLayerCache->freeAll();
     fGpu->markContextDirty();
 }
 
@@ -214,6 +218,7 @@ void GrContext::freeGpuResources() {
 
     fTextureCache->purgeAllUnlocked();
     fFontCache->freeAll();
+    fLayerCache->freeAll();
     // a path renderer may be holding onto resources
     SkSafeSetNull(fPathRendererChain);
     SkSafeSetNull(fSoftwarePathRenderer);
diff --git a/src/gpu/GrLayerCache.cpp b/src/gpu/GrLayerCache.cpp
new file mode 100644 (file)
index 0000000..4120c54
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "GrAtlas.h"
+#include "GrGpu.h"
+#include "GrLayerCache.h"
+
+/**
+ *  PictureLayerKey just wraps a saveLayer's id in the picture for GrTHashTable.
+ */
+class GrLayerCache::PictureLayerKey {
+public:
+    PictureLayerKey(uint32_t pictureID, int layerID) 
+        : fPictureID(pictureID)
+        , fLayerID(layerID) {
+    }
+
+    uint32_t pictureID() const { return fPictureID; }
+    int layerID() const { return fLayerID; }
+
+    uint32_t getHash() const { return (fPictureID << 16) | fLayerID; }
+
+    static bool LessThan(const GrAtlasedLayer& layer, const PictureLayerKey& key) {
+        if (layer.pictureID() == key.pictureID()) {
+            return layer.layerID() < key.layerID();
+        }
+
+        return layer.pictureID() < key.pictureID();
+    }
+
+    static bool Equals(const GrAtlasedLayer& layer, const PictureLayerKey& key) {
+        return layer.pictureID() == key.pictureID() && layer.layerID() == key.layerID();
+    }
+
+private:
+    uint32_t fPictureID;
+    int      fLayerID;
+};
+
+GrLayerCache::GrLayerCache(GrGpu* gpu) 
+    : fGpu(SkRef(gpu))
+    , fLayerPool(16) {      // TODO: may need to increase this later
+}
+
+GrLayerCache::~GrLayerCache() {
+}
+
+void GrLayerCache::init() {
+    static const int kAtlasTextureWidth = 1024;
+    static const int kAtlasTextureHeight = 1024;
+
+    SkASSERT(NULL == fAtlasMgr.get());
+
+    // The layer cache only gets 1 plot
+    SkISize textureSize = SkISize::Make(kAtlasTextureWidth, kAtlasTextureHeight);
+    fAtlasMgr.reset(SkNEW_ARGS(GrAtlasMgr, (fGpu, kSkia8888_GrPixelConfig,
+                                            textureSize, 1, 1)));
+}
+
+void GrLayerCache::freeAll() {
+    fLayerHash.deleteAll();
+    fAtlasMgr.free();
+}
+
+GrAtlasedLayer* GrLayerCache::createLayer(SkPicture* picture, int layerID) {
+    GrAtlasedLayer* layer = fLayerPool.alloc();
+
+    SkASSERT(picture->getGenerationID() != SkPicture::kInvalidGenID);
+    layer->init(picture->getGenerationID(), layerID);
+    fLayerHash.insert(PictureLayerKey(picture->getGenerationID(), layerID), layer);
+    return layer;
+}
+
+
+const GrAtlasedLayer* GrLayerCache::findLayerOrCreate(SkPicture* picture, int layerID) {
+    SkASSERT(picture->getGenerationID() != SkPicture::kInvalidGenID);
+    GrAtlasedLayer* layer = fLayerHash.find(PictureLayerKey(picture->getGenerationID(), layerID));
+    if (NULL == layer) {
+        layer = this->createLayer(picture, layerID);
+    }
+    return layer;
+}
diff --git a/src/gpu/GrLayerCache.h b/src/gpu/GrLayerCache.h
new file mode 100644 (file)
index 0000000..a692a02
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrLayerCache_DEFINED
+#define GrLayerCache_DEFINED
+
+#include "GrAllocPool.h"
+#include "GrTHashTable.h"
+#include "GrPictureUtils.h"
+#include "GrRect.h"
+
+class GrAtlasMgr;
+class GrGpu;
+class GrPlot;
+class SkPicture;
+
+// GrAtlasLocation captures an atlased item's position in the atlas. This
+// means the plot in which it resides and its bounds inside the plot.
+// TODO: Make GrGlyph use one of these?
+class GrAtlasLocation {
+public:
+    GrAtlasLocation() : fPlot(NULL) {}
+
+    void set(GrPlot* plot, const GrIRect16& bounds) {
+        fPlot = plot;
+        fBounds = bounds;
+    }
+
+    const GrPlot* plot() const {
+        return fPlot;
+    }
+
+    const GrIRect16& bounds() const {
+        return fBounds;
+    }
+
+private:
+    GrPlot*   fPlot;
+    GrIRect16 fBounds;  // only valid is fPlot != NULL
+};
+
+// A GrAtlasedLayer encapsulates the atlasing information for a single saveLayer.
+// It is roughly equivalent to a GrGlyph in the font caching system
+class GrAtlasedLayer {
+public:
+    GrAtlasedLayer() : fPictureID(SkPicture::kInvalidGenID) { }
+
+    uint32_t pictureID() const { return fPictureID; }
+    int layerID() const { return fLayerID; }
+
+    void init(uint32_t pictureID, int layerID) { 
+        fPictureID = pictureID;
+        fLayerID   = layerID; 
+    }
+
+private:
+    uint32_t        fPictureID;
+    int             fLayerID;        // only valid if fPicture != kInvalidGenID
+    GrAtlasLocation fLocation; 
+};
+
+// The GrLayerCache caches pre-computed saveLayers for later rendering.
+// Unlike the GrFontCache, this cache only has one GrAtlasMgr (for 8888)
+// and one GrPlot (for the entire atlas). As such, the GrLayerCache
+// roughly combines the functionality of the GrFontCache and GrTextStrike
+// classes.
+class GrLayerCache {
+public:
+    GrLayerCache(GrGpu*);
+    ~GrLayerCache();
+
+    void freeAll();
+
+    const GrAtlasedLayer* findLayerOrCreate(SkPicture* picture, int id);
+
+private:
+    SkAutoTUnref<GrGpu>       fGpu;
+    SkAutoTDelete<GrAtlasMgr> fAtlasMgr; // TODO: could lazily allocate
+
+    class PictureLayerKey;
+    GrTHashTable<GrAtlasedLayer, PictureLayerKey, 7> fLayerHash;
+    GrTAllocPool<GrAtlasedLayer> fLayerPool;
+
+    void init();
+    GrAtlasedLayer* createLayer(SkPicture* picture, int id);
+
+};
+
+#endif
index 052e669..ee4850f 100644 (file)
@@ -14,6 +14,7 @@
 #include "GrContext.h"
 #include "GrBitmapTextContext.h"
 #include "GrDistanceFieldTextContext.h"
+#include "GrLayerCache.h"
 #include "GrPictureUtils.h"
 
 #include "SkGrTexturePixelRef.h"
@@ -2033,7 +2034,9 @@ bool SkGpuDevice::EXPERIMENTAL_drawPicture(SkPicture* picture) {
     SkDebugf("Need SaveLayers: ");
     for (int i = 0; i < gpuData->numSaveLayers(); ++i) {
         if (pullForward[i]) {
-            SkDebugf("%d, ", i);
+            const GrAtlasedLayer* layer = fContext->getLayerCache()->findLayerOrCreate(picture, i);
+
+            SkDebugf("%d (%d), ", i, layer->layerID());
         }
     }
     SkDebugf("\n");