1/*
2 * Copyright 2014 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 "GrProgramElement.h"
9#include "GrGpuResourceRef.h"
10
11uint32_t GrProgramElement::CreateUniqueID() {
12    static int32_t gUniqueID = SK_InvalidUniqueID;
13    uint32_t id;
14    do {
15        id = static_cast<uint32_t>(sk_atomic_inc(&gUniqueID) + 1);
16    } while (id == SK_InvalidUniqueID);
17    return id;
18}
19
20void GrProgramElement::convertRefToPendingExecution() const {
21    // This function makes it so that all the GrGpuResourceRefs own a single ref to their
22    // underlying GrGpuResource if there are any refs to the GrProgramElement and a single
23    // pending read/write if there are any pending executions of the GrProgramElement. The
24    // GrGpuResourceRef will give up its single ref and/or pending read/write in its destructor.
25    SkASSERT(fRefCnt > 0);
26    if (0 == fPendingExecutions) {
27        for (int i = 0; i < fGpuResources.count(); ++i) {
28            fGpuResources[i]->markPendingIO();
29        }
30    }
31    ++fPendingExecutions;
32    this->unref();
33    if (0 == fRefCnt) {
34        for (int i = 0; i < fGpuResources.count(); ++i) {
35            fGpuResources[i]->removeRef();
36        }
37    }
38}
39
40void GrProgramElement::completedExecution() const {
41    this->validate();
42    --fPendingExecutions;
43    if (0 == fPendingExecutions) {
44        if (0 == fRefCnt) {
45            SkDELETE(this);
46        } else {
47            // Now our pending executions have ocurred and we still have refs. Convert
48            // ownership of our resources back to regular refs.
49            for (int i = 0; i < fGpuResources.count(); ++i) {
50                fGpuResources[i]->pendingIOComplete();
51            }
52
53        }
54    }
55}
56