| /* |
| * 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 "GrProgramElement.h" |
| #include "GrGpuResourceRef.h" |
| |
| uint32_t GrProgramElement::CreateUniqueID() { |
| static int32_t gUniqueID = SK_InvalidUniqueID; |
| uint32_t id; |
| do { |
| id = static_cast<uint32_t>(sk_atomic_inc(&gUniqueID) + 1); |
| } while (id == SK_InvalidUniqueID); |
| return id; |
| } |
| |
| void GrProgramElement::convertRefToPendingExecution() const { |
| // This function makes it so that all the GrGpuResourceRefs own a single ref to their |
| // underlying GrGpuResource if there are any refs to the GrProgramElement and a single |
| // pending read/write if there are any pending executions of the GrProgramElement. The |
| // GrGpuResourceRef will give up its single ref and/or pending read/write in its destructor. |
| SkASSERT(fRefCnt > 0); |
| if (0 == fPendingExecutions) { |
| for (int i = 0; i < fGpuResources.count(); ++i) { |
| fGpuResources[i]->markPendingIO(); |
| } |
| } |
| ++fPendingExecutions; |
| this->unref(); |
| if (0 == fRefCnt) { |
| this->removeRefs(); |
| } |
| } |
| |
| void GrProgramElement::completedExecution() const { |
| this->validate(); |
| --fPendingExecutions; |
| if (0 == fPendingExecutions) { |
| if (0 == fRefCnt) { |
| SkDELETE(this); |
| } else { |
| // Now our pending executions have ocurred and we still have refs. Convert |
| // ownership of our resources back to regular refs. |
| for (int i = 0; i < fGpuResources.count(); ++i) { |
| fGpuResources[i]->pendingIOComplete(); |
| } |
| |
| } |
| } |
| } |
| |
| void GrProgramElement::removeRefs() const { |
| for (int i = 0; i < fGpuResources.count(); ++i) { |
| fGpuResources[i]->removeRef(); |
| } |
| } |