Revert of Add abilitly to query audit trail for batches by draw op (patchset #4 id...
authorjoshualitt <joshualitt@google.com>
Mon, 29 Feb 2016 14:32:24 +0000 (06:32 -0800)
committerCommit bot <commit-bot@chromium.org>
Mon, 29 Feb 2016 14:32:24 +0000 (06:32 -0800)
Reason for revert:
kInvalidID conflicts with an older xCode #define

Original issue's description:
> Add abilitly to query audit trail for batches by draw op
>
> BUG=skia:
> GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1745513002
>
> Committed: https://skia.googlesource.com/skia/+/9b48a6e3f862076018cc7d63b180b6340f4873cd

TBR=ethannicholas@google.com,jcgregorio@google.com,joshualitt@chromium.org
# Skipping CQ checks because original CL landed less than 1 days ago.
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=skia:

Review URL: https://codereview.chromium.org/1747893002

include/private/GrAuditTrail.h
src/gpu/GrAuditTrail.cpp
tools/debugger/SkDebugCanvas.cpp
tools/debugger/SkDrawCommand.cpp
tools/debugger/SkDrawCommand.h
tools/skiaserve/Request.cpp
tools/skiaserve/Request.h

index faf59ab..7270864 100644 (file)
@@ -28,8 +28,27 @@ class GrBatch;
 class GrAuditTrail {
 public:
     GrAuditTrail() 
-    : fClientID(kInvalidID)
-    , fEnabled(false) {}
+    : fEnabled(false)
+    , fUniqueID(0) {}
+
+    class AutoFrame {
+    public:
+        AutoFrame(GrAuditTrail* auditTrail, const char* name)
+            : fAuditTrail(auditTrail) {
+            if (fAuditTrail->fEnabled) {
+                fAuditTrail->pushFrame(name);
+            }
+        }
+
+        ~AutoFrame() {
+            if (fAuditTrail->fEnabled) {
+                fAuditTrail->popFrame();
+            }
+        }
+
+    private:
+        GrAuditTrail* fAuditTrail;
+    };
 
     class AutoEnable {
     public:
@@ -64,113 +83,99 @@ public:
         GrAuditTrail* fAuditTrail;
     };
 
-    class AutoCollectBatches {
-    public:
-        AutoCollectBatches(GrAuditTrail* auditTrail, int clientID)
-            : fAutoEnable(auditTrail)
-            , fAuditTrail(auditTrail) {
-            fAuditTrail->setClientID(clientID);
+    void pushFrame(const char* name) {
+        SkASSERT(fEnabled);
+        Frame* frame = new Frame;
+        fEvents.emplace_back(frame);
+        if (fStack.empty()) {
+            fFrames.push_back(frame);
+        } else {
+            fStack.back()->fChildren.push_back(frame);
         }
 
-        ~AutoCollectBatches() { fAuditTrail->setClientID(kInvalidID); }
+        frame->fUniqueID = fUniqueID++;
+        frame->fName = name;
+        fStack.push_back(frame);
+    }
 
-    private:
-        AutoEnable fAutoEnable;
-        GrAuditTrail* fAuditTrail;
-    };
+    void popFrame() {
+        SkASSERT(fEnabled);
+        fStack.pop_back();
+    }
 
     void addBatch(const char* name, const SkRect& bounds) {
-        SkASSERT(fEnabled);
+        SkASSERT(fEnabled && !fStack.empty());
         Batch* batch = new Batch;
-        fBatchPool.emplace_back(batch);
+        fEvents.emplace_back(batch);
+        fStack.back()->fChildren.push_back(batch);
         batch->fName = name;
         batch->fBounds = bounds;
-        batch->fClientID = kInvalidID;
-        batch->fBatchListID = kInvalidID;
-        batch->fChildID = kInvalidID;
         fCurrentBatch = batch;
-        
-        if (fClientID != kInvalidID) {
-            batch->fClientID = fClientID;
-            Batches** batchesLookup = fClientIDLookup.find(fClientID);
-            Batches* batches = nullptr;
-            if (!batchesLookup) {
-                batches = new Batches;
-                fClientIDLookup.set(fClientID, batches);
-            } else {
-                batches = *batchesLookup;
-            }
-
-            batches->push_back(fCurrentBatch);
-        }
     }
 
     void batchingResultCombined(GrBatch* combiner);
 
     void batchingResultNew(GrBatch* batch);
 
-    // Because batching is heavily dependent on sequence of draw calls, these calls will only
-    // produce valid information for the given draw sequence which preceeded them.
-    // Specifically, future draw calls may change the batching and thus would invalidate
-    // the json.  What this means is that for some sequence of draw calls N, the below toJson
-    // calls will only produce JSON which reflects N draw calls.  This JSON may or may not be
-    // accurate for N + 1 or N - 1 draws depending on the actual batching algorithm used.
-    SkString toJson(bool prettyPrint = false) const;
-
-    // returns a json string of all of the batches associated with a given client id
-    SkString toJson(int clientID, bool prettyPrint = false) const;
+    SkString toJson(bool batchList = false, bool prettyPrint = false) const;
 
     bool isEnabled() { return fEnabled; }
     void setEnabled(bool enabled) { fEnabled = enabled; }
 
-    void setClientID(int clientID) { fClientID = clientID; }
+    void reset() { 
+        SkASSERT(fEnabled && fStack.empty());
+        fFrames.reset();
+    }
 
-    void fullReset() {
+    void resetBatchList() {
         SkASSERT(fEnabled);
-        fBatchList.reset();
+        fBatches.reset();
         fIDLookup.reset();
-        // free all client batches
-        fClientIDLookup.foreach([](const int&, Batches** batches) { delete *batches; });
-        fClientIDLookup.reset();
-        fBatchPool.reset(); // must be last, frees all of the memory
     }
 
-    static const int kInvalidID;
+    void fullReset() {
+        SkASSERT(fEnabled);
+        this->reset();
+        this->resetBatchList();
+        fEvents.reset(); // must be last, frees all of the memory
+    }
 
 private:
     // TODO if performance becomes an issue, we can move to using SkVarAlloc
-    struct Batch {
-        SkString toJson() const;
-        SkString fName;
-        SkRect fBounds;
-        int fClientID;
-        int fBatchListID;
-        int fChildID;
+    struct Event {
+        virtual ~Event() {}
+        virtual SkString toJson() const=0;
+
+        const char* fName;
+        uint64_t fUniqueID;
     };
-    typedef SkTArray<SkAutoTDelete<Batch>, true> BatchPool;
 
-    typedef SkTArray<Batch*> Batches;
+    struct Frame : public Event {
+        SkString toJson() const override;
+        SkTArray<Event*> fChildren;
+    };
 
-    struct BatchNode {
-        SkString toJson() const;
+    struct Batch : public Event {
+        SkString toJson() const override;
         SkRect fBounds;
-        Batches fChildren;
+        SkTArray<Batch*> fChildren;
     };
-    typedef SkTArray<SkAutoTDelete<BatchNode>, true> BatchList;
+    typedef SkTArray<SkAutoTDelete<Event>, true> EventArrayPool;
 
     template <typename T>
     static void JsonifyTArray(SkString* json, const char* name, const T& array,
                               bool addComma);
 
+    // We store both an array of frames, and also a flatter array just of the batches
+    bool fEnabled;
+    EventArrayPool fEvents; // manages the lifetimes of the events
+    SkTArray<Event*> fFrames;
+    SkTArray<Frame*> fStack;
+    uint64_t fUniqueID;
+   
     Batch* fCurrentBatch;
-    BatchPool fBatchPool;
     SkTHashMap<GrBatch*, int> fIDLookup;
-    SkTHashMap<int, Batches*> fClientIDLookup;
-    BatchList fBatchList;
-
-    // The client cas pass in an optional client ID which we will use to mark the batches
-    int fClientID;
-    bool fEnabled;
+    SkTArray<Batch*> fBatches;
 };
 
 #define GR_AUDIT_TRAIL_INVOKE_GUARD(audit_trail, invoke, ...) \
@@ -179,11 +184,10 @@ private:
     }
 
 #define GR_AUDIT_TRAIL_AUTO_FRAME(audit_trail, framename) \
-    // TODO fill out the frame stuff
-    //GrAuditTrail::AutoFrame SK_MACRO_APPEND_LINE(auto_frame)(audit_trail, framename);
+    GrAuditTrail::AutoFrame SK_MACRO_APPEND_LINE(auto_frame)(audit_trail, framename);
 
 #define GR_AUDIT_TRAIL_RESET(audit_trail) \
-    //GR_AUDIT_TRAIL_INVOKE_GUARD(audit_trail, reset);
+    GR_AUDIT_TRAIL_INVOKE_GUARD(audit_trail, reset);
 
 #define GR_AUDIT_TRAIL_ADDBATCH(audit_trail, batchname, bounds) \
     GR_AUDIT_TRAIL_INVOKE_GUARD(audit_trail, addBatch, batchname, bounds);
index dae5022..59201f4 100644 (file)
@@ -8,36 +8,29 @@
 #include "GrAuditTrail.h"
 #include "batches/GrBatch.h"
 
-const int GrAuditTrail::kInvalidID = -1;
-
 void GrAuditTrail::batchingResultCombined(GrBatch* combiner) {
     int* indexPtr = fIDLookup.find(combiner);
     SkASSERT(indexPtr);
     int index = *indexPtr;
-    SkASSERT(index < fBatchList.count());
-    BatchNode& batch = *fBatchList[index];
-
-    // set the ids for the child batch
-    fCurrentBatch->fBatchListID = index;
-    fCurrentBatch->fChildID = batch.fChildren.count();
-
-    // Update the bounds and store a pointer to the new batch
+    SkASSERT(index < fBatches.count());
+    Batch& batch = *fBatches[index];
+
+    // if this is our first child, we also push back a copy of the original batch and its
+    // bounds
+    if (batch.fChildren.empty()) {
+        Batch* firstBatch = new Batch;
+        firstBatch->fName = batch.fName;
+        firstBatch->fBounds = batch.fBounds;
+        fEvents.emplace_back(firstBatch);
+        batch.fChildren.push_back(firstBatch);
+    } 
     batch.fChildren.push_back(fCurrentBatch);
     batch.fBounds = combiner->bounds();
 }
 
 void GrAuditTrail::batchingResultNew(GrBatch* batch) {
-    // Our algorithm doesn't bother to reorder inside of a BatchNode
-    // so the ChildID will start at 0
-    fCurrentBatch->fBatchListID = fBatchList.count();
-    fCurrentBatch->fChildID = 0;
-
-    // We use the batch pointer as a key to find the batchnode we are 'glomming' batches onto
-    fIDLookup.set(batch, fCurrentBatch->fBatchListID);
-    BatchNode* batchNode = new BatchNode;
-    batchNode->fBounds = fCurrentBatch->fBounds;
-    batchNode->fChildren.push_back(fCurrentBatch);
-    fBatchList.emplace_back(batchNode);
+    fIDLookup.set(batch, fBatches.count());
+    fBatches.push_back(fCurrentBatch);
 }
 
 template <typename T>
@@ -125,27 +118,15 @@ static SkString pretty_print_json(SkString json) {
     return prettyPrintJson.prettify(json);
 }
 
-SkString GrAuditTrail::toJson(bool prettyPrint) const {
+SkString GrAuditTrail::toJson(bool batchList, bool prettyPrint) const {
     SkString json;
     json.append("{");
-    JsonifyTArray(&json, "Batches", fBatchList, false);
-    json.append("}");
-
-    if (prettyPrint) {
-        return pretty_print_json(json);
+    if (!batchList) {
+        JsonifyTArray(&json, "Stacks", fFrames, false);
     } else {
-        return json;
-    }
-}
-
-SkString GrAuditTrail::toJson(int clientID, bool prettyPrint) const {
-    SkString json;
-    json.append("{");
-    Batches** batches = fClientIDLookup.find(clientID);
-    if (batches) {
-        JsonifyTArray(&json, "Batches", **batches, false);
+        JsonifyTArray(&json, "Batches", fBatches, false);
     }
-    json.appendf("}");
+    json.append("}");
 
     if (prettyPrint) {
         return pretty_print_json(json);
@@ -154,32 +135,26 @@ SkString GrAuditTrail::toJson(int clientID, bool prettyPrint) const {
     }
 }
 
-static void skrect_to_json(SkString* json, const char* name, const SkRect& rect) {
-    json->appendf("\"%s\": {", name);
-    json->appendf("\"Left\": %f,", rect.fLeft);
-    json->appendf("\"Right\": %f,", rect.fRight);
-    json->appendf("\"Top\": %f,", rect.fTop);
-    json->appendf("\"Bottom\": %f", rect.fBottom);
-    json->append("}");
-}
-
-SkString GrAuditTrail::Batch::toJson() const {
+SkString GrAuditTrail::Frame::toJson() const {
     SkString json;
     json.append("{");
-    json.appendf("\"Name\": \"%s\",", fName.c_str());
-    json.appendf("\"ClientID\": \"%d\",", fClientID);
-    json.appendf("\"BatchListID\": \"%d\",", fBatchListID);
-    json.appendf("\"ChildID\": \"%d\",", fChildID);
-    skrect_to_json(&json, "Bounds", fBounds);
+    json.appendf("\"Name\": \"%s\"", fName);
+    JsonifyTArray(&json, "Frames", fChildren, true);
     json.append("}");
     return json;
 }
 
-SkString GrAuditTrail::BatchNode::toJson() const {
+SkString GrAuditTrail::Batch::toJson() const {
     SkString json;
     json.append("{");
-    skrect_to_json(&json, "Bounds", fBounds);
-    JsonifyTArray(&json, "Batches", fChildren, true);
+    json.appendf("\"Name\": \"%s\",", fName);
+    json.append("\"Bounds\": {");
+    json.appendf("\"Left\": %f,", fBounds.fLeft);
+    json.appendf("\"Right\": %f,", fBounds.fRight);
+    json.appendf("\"Top\": %f,", fBounds.fTop);
+    json.appendf("\"Bottom\": %f", fBounds.fBottom);
+    JsonifyTArray(&json, "Children", fChildren, true);
+    json.append("}");
     json.append("}");
     return json;
 }
index cc1733b..34e582e 100644 (file)
@@ -336,8 +336,7 @@ Json::Value SkDebugCanvas::toJSON(UrlDataManager& urlDataManager, int n, SkCanva
     result[SKDEBUGCANVAS_ATTRIBUTE_VERSION] = Json::Value(SKDEBUGCANVAS_VERSION);
     Json::Value commands = Json::Value(Json::arrayValue);
     for (int i = 0; i < this->getSize() && i <= n; i++) {
-        commands[i] = this->getDrawCommandAt(i)->drawToAndCollectJSON(canvas, urlDataManager,
-                                                                      i);
+        commands[i] = this->getDrawCommandAt(i)->drawToAndCollectJSON(canvas, urlDataManager);
     }
     result[SKDEBUGCANVAS_ATTRIBUTE_COMMANDS] = commands;
     return result;
index 1af2998..33e49ce 100644 (file)
@@ -228,8 +228,7 @@ Json::Value SkDrawCommand::toJSON(UrlDataManager& urlDataManager) const {
 }
 
 Json::Value SkDrawCommand::drawToAndCollectJSON(SkCanvas* canvas,
-                                                UrlDataManager& urlDataManager,
-                                                int opIndex) const {
+                                                UrlDataManager& urlDataManager) const {
     Json::Value result = this->toJSON(urlDataManager);
 
     SkASSERT(canvas);
@@ -240,18 +239,19 @@ Json::Value SkDrawCommand::drawToAndCollectJSON(SkCanvas* canvas,
         GrContext* ctx = rt->getContext();
         if(ctx) {
             GrAuditTrail* at = ctx->getAuditTrail();
-            GrAuditTrail::AutoCollectBatches enable(at, opIndex);
+            GrAuditTrail::AutoEnable enable(at);
             this->execute(canvas);
 
             // TODO if this is inefficient we could add a method to GrAuditTrail which takes
             // a Json::Value and is only compiled in this file
             Json::Value parsedFromString;
             Json::Reader reader;
-            SkDEBUGCODE(bool parsingSuccessful = )reader.parse(at->toJson(opIndex).c_str(),
+            SkDEBUGCODE(bool parsingSuccessful = )reader.parse(at->toJson().c_str(),
                                                                parsedFromString);
             SkASSERT(parsingSuccessful);
 
             result[SKDEBUGCANVAS_ATTRIBUTE_AUDITTRAIL] = parsedFromString;
+            at->reset();
         }
     }
 #endif
index 74c2b2c..34832a7 100644 (file)
@@ -102,8 +102,7 @@ public:
 
     virtual Json::Value toJSON(UrlDataManager& urlDataManager) const;
 
-    Json::Value drawToAndCollectJSON(SkCanvas*, UrlDataManager& urlDataManager,
-                                     int opIndex) const;
+    Json::Value drawToAndCollectJSON(SkCanvas*, UrlDataManager& urlDataManager) const;
 
     /* Converts a JSON representation of a command into a newly-allocated SkDrawCommand object. It
      * is the caller's responsibility to delete this object. This method may return null if an error
index 98b3b03..c5a36cb 100644 (file)
@@ -152,28 +152,6 @@ bool Request::initPictureFromStream(SkStream* stream) {
     return true;
 }
 
-GrAuditTrail* Request::getAuditTrail(SkCanvas* canvas) {
-    GrAuditTrail* at = nullptr;
-#if SK_SUPPORT_GPU
-    GrRenderTarget* rt = canvas->internal_private_accessTopLayerRenderTarget();
-    if (rt) {
-        GrContext* ctx = rt->getContext();
-        if (ctx) {
-            at = ctx->getAuditTrail();
-        }
-    }
-#endif
-    return at;
-}
-
-void Request::cleanupAuditTrail(SkCanvas* canvas) {
-    GrAuditTrail* at = this->getAuditTrail(canvas);
-    if (at) {
-        GrAuditTrail::AutoEnable ae(at);
-        at->fullReset();
-    }
-}
-
 SkData* Request::getJsonOps(int n) {
     SkCanvas* canvas = this->getCanvas();
     Json::Value root = fDebugCanvas->toJSON(fUrlDataManager, n, canvas);
@@ -181,8 +159,6 @@ SkData* Request::getJsonOps(int n) {
     SkDynamicMemoryWStream stream;
     stream.writeText(Json::FastWriter().write(root).c_str());
 
-    this->cleanupAuditTrail(canvas);
-
     return stream.copyToData();
 }
 
@@ -194,7 +170,11 @@ SkData* Request::getJsonBatchList(int n) {
     // a Json::Value and is only compiled in this file
     Json::Value parsedFromString;
 #if SK_SUPPORT_GPU
-    GrAuditTrail* at = this->getAuditTrail(canvas);
+    GrRenderTarget* rt = canvas->internal_private_accessTopLayerRenderTarget();
+    SkASSERT(rt);
+    GrContext* ctx = rt->getContext();
+    SkASSERT(ctx);
+    GrAuditTrail* at = ctx->getAuditTrail();
     GrAuditTrail::AutoManageBatchList enable(at);
     
     fDebugCanvas->drawTo(canvas, n);
index 60a59a7..fd015dc 100644 (file)
@@ -60,8 +60,6 @@ private:
     void drawToCanvas(int n);
     SkSurface* createCPUSurface();
     SkSurface* createGPUSurface();
-    GrAuditTrail* getAuditTrail(SkCanvas*);
-    void cleanupAuditTrail(SkCanvas*);
     
     SkAutoTUnref<SkPicture> fPicture;
     SkAutoTDelete<GrContextFactory> fContextFactory;