void CompositableParentManager::ReturnTextureDataIfNecessary(CompositableHost* aCompositable, EditReplyVector& replyv, PCompositableParent* aParent) { if (!aCompositable || !aCompositable->GetCompositableBackendSpecificData()) { return; } const std::vector< RefPtr<TextureHost> > textureList = aCompositable->GetCompositableBackendSpecificData()->GetPendingReleaseFenceTextureList(); // Return pending Texture data for (size_t i = 0; i < textureList.size(); i++) { // File descriptor number is limited to 4 per IPC message. // See Bug 986253 if (mPrevFenceHandles.size() >= 4) { break; } TextureHostOGL* hostOGL = textureList[i]->AsHostOGL(); PTextureParent* actor = textureList[i]->GetIPDLActor(); if (!hostOGL || !actor) { continue; } android::sp<android::Fence> fence = hostOGL->GetAndResetReleaseFence(); if (fence.get() && fence->isValid()) { FenceHandle handle = FenceHandle(fence); replyv.push_back(ReturnReleaseFence(aParent, nullptr, actor, nullptr, handle)); // Hold fence handle to prevent fence's file descriptor is closed before IPC happens. mPrevFenceHandles.push_back(handle); } } aCompositable->GetCompositableBackendSpecificData()->ClearPendingReleaseFenceTextureList(); }
bool HwcComposer2D::Commit() { hwc_display_contents_1_t *displays[HWC_NUM_DISPLAY_TYPES] = { nullptr }; displays[HWC_DISPLAY_PRIMARY] = mList; for (uint32_t j=0; j < (mList->numHwLayers - 1); j++) { mList->hwLayers[j].acquireFenceFd = -1; if (mHwcLayerMap.IsEmpty() || (mList->hwLayers[j].compositionType == HWC_FRAMEBUFFER)) { continue; } LayerRenderState state = mHwcLayerMap[j]->GetLayer()->GetRenderState(); if (!state.mTexture) { continue; } TextureHostOGL* texture = state.mTexture->AsHostOGL(); if (!texture) { continue; } sp<Fence> fence = texture->GetAndResetAcquireFence(); if (fence.get() && fence->isValid()) { mList->hwLayers[j].acquireFenceFd = fence->dup(); } } int err = mHwc->set(mHwc, HWC_NUM_DISPLAY_TYPES, displays); mPrevDisplayFence = mPrevRetireFence; mPrevRetireFence = Fence::NO_FENCE; for (uint32_t j=0; j < (mList->numHwLayers - 1); j++) { if (mList->hwLayers[j].releaseFenceFd >= 0) { int fd = mList->hwLayers[j].releaseFenceFd; mList->hwLayers[j].releaseFenceFd = -1; sp<Fence> fence = new Fence(fd); LayerRenderState state = mHwcLayerMap[j]->GetLayer()->GetRenderState(); if (!state.mTexture) { continue; } TextureHostOGL* texture = state.mTexture->AsHostOGL(); if (!texture) { continue; } texture->SetReleaseFence(fence); } } if (mList->retireFenceFd >= 0) { mPrevRetireFence = new Fence(mList->retireFenceFd); } mPrepared = false; return !err; }
void TiledLayerBufferComposite::SetReleaseFence(const android::sp<android::Fence>& aReleaseFence) { for (size_t i = 0; i < mRetainedTiles.Length(); i++) { if (!mRetainedTiles[i].mTextureHost) { continue; } TextureHostOGL* texture = mRetainedTiles[i].mTextureHost->AsHostOGL(); if (!texture) { continue; } texture->SetReleaseFence(new android::Fence(aReleaseFence->dup())); } }
FenceHandle TextureHost::GetAndResetReleaseFenceHandle() { #if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17 TextureHostOGL* hostOGL = this->AsHostOGL(); if (!hostOGL) { return FenceHandle(); } android::sp<android::Fence> fence = hostOGL->GetAndResetReleaseFence(); if (fence.get() && fence->isValid()) { FenceHandle handle = FenceHandle(fence); return handle; } #endif return FenceHandle(); }
void TextureParent::SendFenceHandleIfPresent() { #if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17 if (mTextureHost) { TextureHostOGL* hostOGL = mTextureHost->AsHostOGL(); if (!hostOGL) { return; } android::sp<android::Fence> fence = hostOGL->GetAndResetReleaseFence(); if (fence.get() && fence->isValid()) { // HWC might not provide Fence. // In this case, HWC implicitly handles buffer's fence. FenceHandle handle = FenceHandle(fence); RefPtr<FenceDeliveryTracker> tracker = new FenceDeliveryTracker(handle); mCompositableManager->SendFenceHandle(tracker, this, handle); } } #endif }
bool LayerTransactionParent::RecvChildAsyncMessages(const InfallibleTArray<AsyncChildMessageData>& aMessages) { for (AsyncChildMessageArray::index_type i = 0; i < aMessages.Length(); ++i) { const AsyncChildMessageData& message = aMessages[i]; switch (message.type()) { case AsyncChildMessageData::TOpDeliverFenceFromChild: { const OpDeliverFenceFromChild& op = message.get_OpDeliverFenceFromChild(); #if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17 FenceHandle fence = FenceHandle(op.fence()); PTextureParent* parent = op.textureParent(); TextureHostOGL* hostOGL = nullptr; RefPtr<TextureHost> texture = TextureHost::AsTextureHost(parent); if (texture) { hostOGL = texture->AsHostOGL(); } if (hostOGL) { hostOGL->SetAcquireFence(fence.mFence); } #endif // Send back a response. InfallibleTArray<AsyncParentMessageData> replies; replies.AppendElement(OpReplyDeliverFence(op.transactionId())); mozilla::unused << SendParentAsyncMessages(replies); break; } case AsyncChildMessageData::TOpReplyDeliverFence: { const OpReplyDeliverFence& op = message.get_OpReplyDeliverFence(); TransactionCompleteted(op.transactionId()); break; } default: NS_ERROR("unknown AsyncChildMessageData type"); return false; } } return true; }
void TextureParent::CompositorRecycle() { mTextureHost->ClearRecycleCallback(); MaybeFenceHandle handle = null_t(); #if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17 if (mTextureHost) { TextureHostOGL* hostOGL = mTextureHost->AsHostOGL(); android::sp<android::Fence> fence = hostOGL->GetAndResetReleaseFence(); if (fence.get() && fence->isValid()) { handle = FenceHandle(fence); // HWC might not provide Fence. // In this case, HWC implicitly handles buffer's fence. } } #endif mozilla::unused << SendCompositorRecycle(handle); // Don't forget to prepare for the next reycle mWaitForClientRecycle = mTextureHost; }