Home | History | Annotate | Download | only in gpu
      1 /*
      2  * Copyright 2016 Google Inc.
      3  *
      4  * Use of this source code is governed by a BSD-style license that can be
      5  * found in the LICENSE file.
      6  */
      7 
      8 #include "GrOpList.h"
      9 
     10 #include "GrContext.h"
     11 #include "GrSurfaceProxy.h"
     12 
     13 #include "SkAtomics.h"
     14 
     15 uint32_t GrOpList::CreateUniqueID() {
     16     static int32_t gUniqueID = SK_InvalidUniqueID;
     17     uint32_t id;
     18     // Loop in case our global wraps around, as we never want to return a 0.
     19     do {
     20         id = static_cast<uint32_t>(sk_atomic_inc(&gUniqueID) + 1);
     21     } while (id == SK_InvalidUniqueID);
     22     return id;
     23 }
     24 
     25 GrOpList::GrOpList(GrResourceProvider* resourceProvider,
     26                    GrSurfaceProxy* surfaceProxy, GrAuditTrail* auditTrail)
     27     : fAuditTrail(auditTrail)
     28     , fUniqueID(CreateUniqueID())
     29     , fFlags(0) {
     30     fTarget.setProxy(sk_ref_sp(surfaceProxy), kWrite_GrIOType);
     31     fTarget.get()->setLastOpList(this);
     32 
     33     // MDB TODO: remove this! We are currently moving to having all the ops that target
     34     // the RT as a dest (e.g., clear, etc.) rely on the opList's 'fTarget' pointer
     35     // for the IO Ref. This works well but until they are all swapped over (and none
     36     // are pre-emptively instantiating proxies themselves) we need to instantiate
     37     // here so that the GrSurfaces are created in an order that preserves the GrSurface
     38     // re-use assumptions.
     39     fTarget.get()->instantiate(resourceProvider);
     40     fTarget.markPendingIO();
     41 }
     42 
     43 GrOpList::~GrOpList() {
     44     this->reset();
     45 }
     46 
     47 bool GrOpList::instantiate(GrResourceProvider* resourceProvider) {
     48     return SkToBool(fTarget.get()->instantiate(resourceProvider));
     49 }
     50 
     51 void GrOpList::reset() {
     52     if (fTarget.get() && this == fTarget.get()->getLastOpList()) {
     53         fTarget.get()->setLastOpList(nullptr);
     54     }
     55 
     56     fTarget.reset();
     57     fAuditTrail = nullptr;
     58 }
     59 
     60 // Add a GrOpList-based dependency
     61 void GrOpList::addDependency(GrOpList* dependedOn) {
     62     SkASSERT(!dependedOn->dependsOn(this));  // loops are bad
     63 
     64     if (this->dependsOn(dependedOn)) {
     65         return;  // don't add duplicate dependencies
     66     }
     67 
     68     *fDependencies.push() = dependedOn;
     69 }
     70 
     71 // Convert from a GrSurface-based dependency to a GrOpList one
     72 void GrOpList::addDependency(GrSurfaceProxy* dependedOn, const GrCaps& caps) {
     73     if (dependedOn->getLastOpList()) {
     74         // If it is still receiving dependencies, this GrOpList shouldn't be closed
     75         SkASSERT(!this->isClosed());
     76 
     77         GrOpList* opList = dependedOn->getLastOpList();
     78         if (opList == this) {
     79             // self-read - presumably for dst reads
     80         } else {
     81             this->addDependency(opList);
     82 
     83             // Can't make it closed in the self-read case
     84             opList->makeClosed(caps);
     85         }
     86     }
     87 }
     88 
     89 #ifdef SK_DEBUG
     90 void GrOpList::dump() const {
     91     SkDebugf("--------------------------------------------------------------\n");
     92     SkDebugf("node: %d -> RT: %d\n", fUniqueID, fTarget.get() ? fTarget.get()->uniqueID().asUInt()
     93                                                               : -1);
     94     SkDebugf("relies On (%d): ", fDependencies.count());
     95     for (int i = 0; i < fDependencies.count(); ++i) {
     96         SkDebugf("%d, ", fDependencies[i]->fUniqueID);
     97     }
     98     SkDebugf("\n");
     99 }
    100 #endif
    101