status_t GonkConsumerBase::addReleaseFenceLocked(int slot, const sp<GraphicBuffer> graphicBuffer, const sp<Fence>& fence) { CB_LOGV("addReleaseFenceLocked: slot=%d", slot); // If consumer no longer tracks this graphicBuffer, we can safely // drop this fence, as it will never be received by the producer. if (!stillTracking(slot, graphicBuffer)) { return OK; } if (!mSlots[slot].mFence.get()) { mSlots[slot].mFence = fence; } else { sp<Fence> mergedFence = Fence::merge( String8::format("%.28s:%d", mName.string(), slot), mSlots[slot].mFence, fence); if (!mergedFence.get()) { CB_LOGE("failed to merge release fences"); // synchronization is broken, the best we can do is hope fences // signal in order so the new fence will act like a union mSlots[slot].mFence = fence; return BAD_VALUE; } mSlots[slot].mFence = mergedFence; } return OK; }
status_t ConsumerBase::detachBuffer(int slot) { CB_LOGV("detachBuffer"); Mutex::Autolock lock(mMutex); status_t result = mConsumer->detachBuffer(slot); if (result != NO_ERROR) { CB_LOGE("Failed to detach buffer: %d", result); return result; } freeBufferLocked(slot); return result; }
status_t ConsumerBase::addReleaseFenceLocked(int slot, const sp<Fence>& fence) { CB_LOGV("addReleaseFenceLocked: slot=%d", slot); if (!mSlots[slot].mFence.get()) { mSlots[slot].mFence = fence; } else { sp<Fence> mergedFence = Fence::merge( String8::format("%.28s:%d", mName.string(), slot), mSlots[slot].mFence, fence); if (!mergedFence.get()) { CB_LOGE("failed to merge release fences"); // synchronization is broken, the best we can do is hope fences // signal in order so the new fence will act like a union mSlots[slot].mFence = fence; return BAD_VALUE; } mSlots[slot].mFence = mergedFence; } return OK; }
GonkConsumerBase::GonkConsumerBase(const sp<GonkBufferQueue>& bufferQueue, bool controlledByApp) : mAbandoned(false), mConsumer(bufferQueue) { // Choose a name using the PID and a process-unique ID. mName = String8::format("unnamed-%d-%d", getpid(), createProcessUniqueId()); // Note that we can't create an sp<...>(this) in a ctor that will not keep a // reference once the ctor ends, as that would cause the refcount of 'this' // dropping to 0 at the end of the ctor. Since all we need is a wp<...> // that's what we create. wp<ConsumerListener> listener = static_cast<ConsumerListener*>(this); sp<IConsumerListener> proxy = new GonkBufferQueue::ProxyConsumerListener(listener); status_t err = mConsumer->consumerConnect(proxy, controlledByApp); if (err != NO_ERROR) { CB_LOGE("GonkConsumerBase: error connecting to GonkBufferQueue: %s (%d)", strerror(-err), err); } else { mConsumer->setConsumerName(mName); } }