void WebRenderBridgeParent::CompositeToTarget(gfx::DrawTarget* aTarget, const gfx::IntRect* aRect) { AutoProfilerTracing tracing("Paint", "CompositeToTraget"); if (mPaused) { return; } const uint32_t maxPendingFrameCount = 1; if (!mForceRendering && wr::RenderThread::Get()->GetPendingFrameCount(mApi->GetId()) >= maxPendingFrameCount) { // Render thread is busy, try next time. ScheduleComposition(); return; } bool scheduleComposite = false; nsTArray<wr::WrOpacityProperty> opacityArray; nsTArray<wr::WrTransformProperty> transformArray; mAsyncImageManager->SetCompositionTime(TimeStamp::Now()); mAsyncImageManager->ApplyAsyncImages(mApi); SampleAnimations(opacityArray, transformArray); if (!transformArray.IsEmpty() || !opacityArray.IsEmpty()) { scheduleComposite = true; } if (PushAPZStateToWR(transformArray)) { scheduleComposite = true; } wr::RenderThread::Get()->IncPendingFrameCount(mApi->GetId()); #if defined(ENABLE_FRAME_LATENCY_LOG) auto startTime = TimeStamp::Now(); mApi->SetFrameStartTime(startTime); #endif if (!transformArray.IsEmpty() || !opacityArray.IsEmpty()) { mApi->GenerateFrame(opacityArray, transformArray); } else { mApi->GenerateFrame(); } if (!mAsyncImageManager->GetCompositeUntilTime().IsNull()) { scheduleComposite = true; } if (scheduleComposite) { ScheduleComposition(); } }
void WebRenderBridgeParent::ProcessWebRenderCommands(const gfx::IntSize &aSize, InfallibleTArray<WebRenderParentCommand>& aCommands, const wr::Epoch& aEpoch, const wr::LayoutSize& aContentSize, const wr::ByteBuffer& dl, const wr::BuiltDisplayListDescriptor& dlDesc, const wr::IdNamespace& aIdNamespace) { mAsyncImageManager->SetCompositionTime(TimeStamp::Now()); ProcessWebRenderParentCommands(aCommands); // The command is obsoleted. // Do not set the command to webrender since it causes crash in webrender. if (mIdNamespace != aIdNamespace) { return; } if (mWidget) { LayoutDeviceIntSize size = mWidget->GetClientSize(); mApi->SetWindowParameters(size); } gfx::Color color = mWidget ? gfx::Color(0.3f, 0.f, 0.f, 1.f) : gfx::Color(0.f, 0.f, 0.f, 0.f); mApi->SetRootDisplayList(color, aEpoch, LayerSize(aSize.width, aSize.height), mPipelineId, aContentSize, dlDesc, dl.mData, dl.mLength); ScheduleComposition(); DeleteOldImages(); if (ShouldParentObserveEpoch()) { mCompositorBridge->ObserveLayerUpdate(GetLayersId(), GetChildLayerObserverEpoch(), true); } }
mozilla::ipc::IPCResult WebRenderBridgeParent::RecvForceComposite() { if (mDestroyed) { return IPC_OK(); } ScheduleComposition(); return IPC_OK(); }
void CompositorParent::ShadowLayersUpdated(LayerTransactionParent* aLayerTree, const uint64_t& aTransactionId, const TargetConfig& aTargetConfig, bool aIsFirstPaint, bool aScheduleComposite, uint32_t aPaintSequenceNumber) { ScheduleRotationOnCompositorThread(aTargetConfig, aIsFirstPaint); // Instruct the LayerManager to update its render bounds now. Since all the orientation // change, dimension change would be done at the stage, update the size here is free of // race condition. mLayerManager->UpdateRenderBounds(aTargetConfig.clientBounds()); mLayerManager->SetRegionToClear(aTargetConfig.clearRegion()); mCompositionManager->Updated(aIsFirstPaint, aTargetConfig); Layer* root = aLayerTree->GetRoot(); mLayerManager->SetRoot(root); if (mApzcTreeManager) { AutoResolveRefLayers resolve(mCompositionManager); mApzcTreeManager->UpdatePanZoomControllerTree(this, root, aIsFirstPaint, mRootLayerTreeID, aPaintSequenceNumber); } MOZ_ASSERT(aTransactionId > mPendingTransaction); mPendingTransaction = aTransactionId; if (root) { SetShadowProperties(root); } if (aScheduleComposite) { ScheduleComposition(); if (mPaused) { DidComposite(); } // When testing we synchronously update the shadow tree with the animated // values to avoid race conditions when calling GetAnimationTransform etc. // (since the above SetShadowProperties will remove animation effects). // However, we only do this update when a composite operation is already // scheduled in order to better match the behavior under regular sampling // conditions. if (mIsTesting && root && mCurrentCompositeTask) { AutoResolveRefLayers resolve(mCompositionManager); bool requestNextFrame = mCompositionManager->TransformShadowTree(mTestTime); if (!requestNextFrame) { CancelCurrentCompositeTask(); // Pretend we composited in case someone is wating for this event. DidComposite(); } } } mLayerManager->NotifyShadowTreeTransaction(); }
void CompositorParent::ShadowLayersUpdated(bool isFirstPaint) { mIsFirstPaint = mIsFirstPaint || isFirstPaint; mLayersUpdated = true; const nsTArray<PLayersParent*>& shadowParents = ManagedPLayersParent(); NS_ABORT_IF_FALSE(shadowParents.Length() <= 1, "can only support at most 1 ShadowLayersParent"); if (shadowParents.Length()) { Layer* root = static_cast<ShadowLayersParent*>(shadowParents[0])->GetRoot(); mLayerManager->SetRoot(root); SetShadowProperties(root); } ScheduleComposition(); }
void CompositorParent::NotifyShadowTreeTransaction(uint64_t aId, bool aIsFirstPaint, bool aScheduleComposite, uint32_t aPaintSequenceNumber) { if (mApzcTreeManager && mLayerManager && mLayerManager->GetRoot()) { AutoResolveRefLayers resolve(mCompositionManager); mApzcTreeManager->UpdatePanZoomControllerTree(this, mLayerManager->GetRoot(), aIsFirstPaint, aId, aPaintSequenceNumber); mLayerManager->NotifyShadowTreeTransaction(); } if (aScheduleComposite) { ScheduleComposition(); } }
void CompositorParent::ForceComposite(LayerTransactionParent* aLayerTree) { ScheduleComposition(); }
void CompositorParent::CompositeToTarget(DrawTarget* aTarget, const nsIntRect* aRect) { profiler_tracing("Paint", "Composite", TRACING_INTERVAL_START); PROFILER_LABEL("CompositorParent", "Composite", js::ProfileEntry::Category::GRAPHICS); MOZ_ASSERT(IsInCompositorThread(), "Composite can only be called on the compositor thread"); #ifdef COMPOSITOR_PERFORMANCE_WARNING TimeDuration scheduleDelta = TimeStamp::Now() - mExpectedComposeStartTime; if (scheduleDelta > TimeDuration::FromMilliseconds(2) || scheduleDelta < TimeDuration::FromMilliseconds(-2)) { printf_stderr("Compositor: Compose starting off schedule by %4.1f ms\n", scheduleDelta.ToMilliseconds()); } #endif mLastCompose = TimeStamp::Now(); if (!CanComposite()) { DidComposite(); return; } AutoResolveRefLayers resolve(mCompositionManager); if (aTarget) { mLayerManager->BeginTransactionWithDrawTarget(aTarget, *aRect); } else { mLayerManager->BeginTransaction(); } if (mForceCompositionTask && !mOverrideComposeReadiness) { if (mCompositionManager->ReadyForCompose()) { mForceCompositionTask->Cancel(); mForceCompositionTask = nullptr; } else { return; } } TimeStamp time = mIsTesting ? mTestTime : mLastCompose; bool requestNextFrame = mCompositionManager->TransformShadowTree(time); if (requestNextFrame) { ScheduleComposition(); } RenderTraceLayers(mLayerManager->GetRoot(), "0000"); mCompositionManager->ComputeRotation(); #ifdef MOZ_DUMP_PAINTING static bool gDumpCompositorTree = false; if (gDumpCompositorTree) { printf_stderr("Painting --- compositing layer tree:\n"); mLayerManager->Dump(); } #endif mLayerManager->SetDebugOverlayWantsNextFrame(false); mLayerManager->EndEmptyTransaction(); if (!aTarget) { DidComposite(); } if (mLayerManager->DebugOverlayWantsNextFrame()) { ScheduleComposition(); } #ifdef COMPOSITOR_PERFORMANCE_WARNING TimeDuration executionTime = TimeStamp::Now() - mLastCompose; TimeDuration frameBudget = TimeDuration::FromMilliseconds(15); int32_t frameRate = CalculateCompositionFrameRate(); if (frameRate > 0) { frameBudget = TimeDuration::FromSeconds(1.0 / frameRate); } if (executionTime > frameBudget) { printf_stderr("Compositor: Composite execution took %4.1f ms\n", executionTime.ToMilliseconds()); } #endif // 0 -> Full-tilt composite if (gfxPrefs::LayersCompositionFrameRate() == 0 || mLayerManager->GetCompositor()->GetDiagnosticTypes() & DiagnosticTypes::FLASH_BORDERS) { // Special full-tilt composite mode for performance testing ScheduleComposition(); } profiler_tracing("Paint", "Composite", TRACING_INTERVAL_END); }
bool CompositableParentManager::ReceiveCompositableUpdate(const CompositableOperation& aEdit, EditReplyVector& replyv) { switch (aEdit.type()) { case CompositableOperation::TOpCreatedIncrementalTexture: { MOZ_LAYERS_LOG(("[ParentSide] Created texture")); const OpCreatedIncrementalTexture& op = aEdit.get_OpCreatedIncrementalTexture(); CompositableHost* compositable = AsCompositable(op); bool success = compositable->CreatedIncrementalTexture(this, op.textureInfo(), op.bufferRect()); if (!success) { return false; } break; } case CompositableOperation::TOpPaintTextureRegion: { MOZ_LAYERS_LOG(("[ParentSide] Paint ThebesLayer")); const OpPaintTextureRegion& op = aEdit.get_OpPaintTextureRegion(); CompositableHost* compositable = AsCompositable(op); Layer* layer = compositable->GetLayer(); if (!layer || layer->GetType() != Layer::TYPE_THEBES) { return false; } ThebesLayerComposite* thebes = static_cast<ThebesLayerComposite*>(layer); const ThebesBufferData& bufferData = op.bufferData(); RenderTraceInvalidateStart(thebes, "FF00FF", op.updatedRegion().GetBounds()); nsIntRegion frontUpdatedRegion; if (!compositable->UpdateThebes(bufferData, op.updatedRegion(), thebes->GetValidRegion(), &frontUpdatedRegion)) { return false; } replyv.push_back( OpContentBufferSwap(op.compositableParent(), nullptr, frontUpdatedRegion)); RenderTraceInvalidateEnd(thebes, "FF00FF"); break; } case CompositableOperation::TOpPaintTextureIncremental: { MOZ_LAYERS_LOG(("[ParentSide] Paint ThebesLayer")); const OpPaintTextureIncremental& op = aEdit.get_OpPaintTextureIncremental(); CompositableHost* compositable = AsCompositable(op); SurfaceDescriptor desc = op.image(); compositable->UpdateIncremental(op.textureId(), desc, op.updatedRegion(), op.bufferRect(), op.bufferRotation()); break; } case CompositableOperation::TOpUpdatePictureRect: { const OpUpdatePictureRect& op = aEdit.get_OpUpdatePictureRect(); CompositableHost* compositable = AsCompositable(op); MOZ_ASSERT(compositable); compositable->SetPictureRect(op.picture()); break; } case CompositableOperation::TOpUseTiledLayerBuffer: { MOZ_LAYERS_LOG(("[ParentSide] Paint TiledLayerBuffer")); const OpUseTiledLayerBuffer& op = aEdit.get_OpUseTiledLayerBuffer(); CompositableHost* compositable = AsCompositable(op); TiledLayerComposer* tileComposer = compositable->AsTiledLayerComposer(); NS_ASSERTION(tileComposer, "compositable is not a tile composer"); const SurfaceDescriptorTiles& tileDesc = op.tileLayerDescriptor(); tileComposer->UseTiledLayerBuffer(this, tileDesc); break; } case CompositableOperation::TOpRemoveTexture: { const OpRemoveTexture& op = aEdit.get_OpRemoveTexture(); CompositableHost* compositable = AsCompositable(op); RefPtr<TextureHost> tex = TextureHost::AsTextureHost(op.textureParent()); MOZ_ASSERT(tex.get()); compositable->RemoveTextureHost(tex); // send FenceHandle if present. TextureHost::SendFenceHandleIfPresent(op.textureParent()); break; } case CompositableOperation::TOpRemoveTextureAsync: { const OpRemoveTextureAsync& op = aEdit.get_OpRemoveTextureAsync(); CompositableHost* compositable = AsCompositable(op); RefPtr<TextureHost> tex = TextureHost::AsTextureHost(op.textureParent()); MOZ_ASSERT(tex.get()); compositable->RemoveTextureHost(tex); if (!IsAsync() && GetChildProcessId()) { // send FenceHandle if present via ImageBridge. ImageBridgeParent::SendFenceHandleToTrackerIfPresent( GetChildProcessId(), op.holderId(), op.transactionId(), op.textureParent()); // If the message is recievied via PLayerTransaction, // Send message back via PImageBridge. ImageBridgeParent::ReplyRemoveTexture( GetChildProcessId(), OpReplyRemoveTexture(true, // isMain op.holderId(), op.transactionId())); } else { // send FenceHandle if present. TextureHost::SendFenceHandleIfPresent(op.textureParent()); ReplyRemoveTexture(OpReplyRemoveTexture(false, // isMain op.holderId(), op.transactionId())); } break; } case CompositableOperation::TOpUseTexture: { const OpUseTexture& op = aEdit.get_OpUseTexture(); CompositableHost* compositable = AsCompositable(op); RefPtr<TextureHost> tex = TextureHost::AsTextureHost(op.textureParent()); MOZ_ASSERT(tex.get()); compositable->UseTextureHost(tex); if (IsAsync()) { ScheduleComposition(op); // Async layer updates don't trigger invalidation, manually tell the layer // that its content have changed. if (compositable->GetLayer()) { compositable->GetLayer()->SetInvalidRectToVisibleRegion(); } } break; } case CompositableOperation::TOpUseComponentAlphaTextures: { const OpUseComponentAlphaTextures& op = aEdit.get_OpUseComponentAlphaTextures(); CompositableHost* compositable = AsCompositable(op); RefPtr<TextureHost> texOnBlack = TextureHost::AsTextureHost(op.textureOnBlackParent()); RefPtr<TextureHost> texOnWhite = TextureHost::AsTextureHost(op.textureOnWhiteParent()); MOZ_ASSERT(texOnBlack && texOnWhite); compositable->UseComponentAlphaTextures(texOnBlack, texOnWhite); if (IsAsync()) { ScheduleComposition(op); } break; } #ifdef MOZ_WIDGET_GONK case CompositableOperation::TOpUseOverlaySource: { const OpUseOverlaySource& op = aEdit.get_OpUseOverlaySource(); CompositableHost* compositable = AsCompositable(op); MOZ_ASSERT(compositable->GetType() == CompositableType::IMAGE_OVERLAY, "Invalid operation!"); compositable->UseOverlaySource(op.overlay()); break; } #endif case CompositableOperation::TOpUpdateTexture: { const OpUpdateTexture& op = aEdit.get_OpUpdateTexture(); RefPtr<TextureHost> texture = TextureHost::AsTextureHost(op.textureParent()); MOZ_ASSERT(texture); texture->Updated(op.region().type() == MaybeRegion::TnsIntRegion ? &op.region().get_nsIntRegion() : nullptr); // no region means invalidate the entire surface break; } default: { MOZ_ASSERT(false, "bad type"); } } return true; }
bool CompositableParentManager::ReceiveCompositableUpdate(const CompositableOperation& aEdit, EditReplyVector& replyv) { switch (aEdit.type()) { case CompositableOperation::TOpCreatedTexture: { MOZ_LAYERS_LOG(("[ParentSide] Created texture")); const OpCreatedTexture& op = aEdit.get_OpCreatedTexture(); CompositableParent* compositableParent = static_cast<CompositableParent*>(op.compositableParent()); CompositableHost* compositable = compositableParent->GetCompositableHost(); compositable->EnsureDeprecatedTextureHost(op.textureId(), op.descriptor(), compositableParent->GetCompositableManager(), op.textureInfo()); break; } case CompositableOperation::TOpCreatedIncrementalTexture: { MOZ_LAYERS_LOG(("[ParentSide] Created texture")); const OpCreatedIncrementalTexture& op = aEdit.get_OpCreatedIncrementalTexture(); CompositableParent* compositableParent = static_cast<CompositableParent*>(op.compositableParent()); CompositableHost* compositable = compositableParent->GetCompositableHost(); compositable->EnsureDeprecatedTextureHostIncremental(compositableParent->GetCompositableManager(), op.textureInfo(), op.bufferRect()); break; } case CompositableOperation::TOpDestroyThebesBuffer: { MOZ_LAYERS_LOG(("[ParentSide] Created double buffer")); const OpDestroyThebesBuffer& op = aEdit.get_OpDestroyThebesBuffer(); CompositableParent* compositableParent = static_cast<CompositableParent*>(op.compositableParent()); CompositableHost* compositableHost = compositableParent->GetCompositableHost(); if (compositableHost->GetType() != BUFFER_CONTENT && compositableHost->GetType() != BUFFER_CONTENT_DIRECT) { return false; } DeprecatedContentHostBase* content = static_cast<DeprecatedContentHostBase*>(compositableHost); content->DestroyTextures(); break; } case CompositableOperation::TOpPaintTexture: { MOZ_LAYERS_LOG(("[ParentSide] Paint Texture X")); const OpPaintTexture& op = aEdit.get_OpPaintTexture(); CompositableParent* compositableParent = static_cast<CompositableParent*>(op.compositableParent()); CompositableHost* compositable = compositableParent->GetCompositableHost(); Layer* layer = compositable ? compositable->GetLayer() : nullptr; LayerComposite* shadowLayer = layer ? layer->AsLayerComposite() : nullptr; if (shadowLayer) { Compositor* compositor = static_cast<LayerManagerComposite*>(layer->Manager())->GetCompositor(); compositable->SetCompositor(compositor); compositable->SetLayer(layer); } else { // if we reach this branch, it most likely means that async textures // are coming in before we had time to attach the compositable to a // layer. Don't panic, it is okay in this case. it should not be // happening continuously, though. } if (layer) { RenderTraceInvalidateStart(layer, "FF00FF", layer->GetVisibleRegion().GetBounds()); } if (compositable) { const SurfaceDescriptor& descriptor = op.image(); compositable->EnsureDeprecatedTextureHost(op.textureId(), descriptor, compositableParent->GetCompositableManager(), TextureInfo()); MOZ_ASSERT(compositable->GetDeprecatedTextureHost()); SurfaceDescriptor newBack; bool shouldRecomposite = compositable->Update(descriptor, &newBack); if (IsSurfaceDescriptorValid(newBack)) { replyv.push_back(OpTextureSwap(compositableParent, nullptr, op.textureId(), newBack)); } if (IsAsync() && shouldRecomposite) { ScheduleComposition(op); } } if (layer) { RenderTraceInvalidateEnd(layer, "FF00FF"); } // return texure data to client if necessary ReturnTextureDataIfNecessary(compositable, replyv, op.compositableParent()); break; } case CompositableOperation::TOpPaintTextureRegion: { MOZ_LAYERS_LOG(("[ParentSide] Paint ThebesLayer")); const OpPaintTextureRegion& op = aEdit.get_OpPaintTextureRegion(); CompositableParent* compositableParent = static_cast<CompositableParent*>(op.compositableParent()); CompositableHost* compositable = compositableParent->GetCompositableHost(); Layer* layer = compositable->GetLayer(); if (!layer || layer->GetType() != Layer::TYPE_THEBES) { return false; } ThebesLayerComposite* thebes = static_cast<ThebesLayerComposite*>(layer); const ThebesBufferData& bufferData = op.bufferData(); RenderTraceInvalidateStart(thebes, "FF00FF", op.updatedRegion().GetBounds()); nsIntRegion frontUpdatedRegion; if (!compositable->UpdateThebes(bufferData, op.updatedRegion(), thebes->GetValidRegion(), &frontUpdatedRegion)) { return false; } replyv.push_back( OpContentBufferSwap(compositableParent, nullptr, frontUpdatedRegion)); RenderTraceInvalidateEnd(thebes, "FF00FF"); // return texure data to client if necessary ReturnTextureDataIfNecessary(compositable, replyv, op.compositableParent()); break; } case CompositableOperation::TOpPaintTextureIncremental: { MOZ_LAYERS_LOG(("[ParentSide] Paint ThebesLayer")); const OpPaintTextureIncremental& op = aEdit.get_OpPaintTextureIncremental(); CompositableParent* compositableParent = static_cast<CompositableParent*>(op.compositableParent()); CompositableHost* compositable = compositableParent->GetCompositableHost(); SurfaceDescriptor desc = op.image(); compositable->UpdateIncremental(op.textureId(), desc, op.updatedRegion(), op.bufferRect(), op.bufferRotation()); break; } case CompositableOperation::TOpUpdatePictureRect: { const OpUpdatePictureRect& op = aEdit.get_OpUpdatePictureRect(); CompositableHost* compositable = static_cast<CompositableParent*>(op.compositableParent())->GetCompositableHost(); MOZ_ASSERT(compositable); compositable->SetPictureRect(op.picture()); break; } case CompositableOperation::TOpUseTiledLayerBuffer: { MOZ_LAYERS_LOG(("[ParentSide] Paint TiledLayerBuffer")); const OpUseTiledLayerBuffer& op = aEdit.get_OpUseTiledLayerBuffer(); CompositableParent* compositableParent = static_cast<CompositableParent*>(op.compositableParent()); CompositableHost* compositable = compositableParent->GetCompositableHost(); TiledLayerComposer* tileComposer = compositable->AsTiledLayerComposer(); NS_ASSERTION(tileComposer, "compositable is not a tile composer"); const SurfaceDescriptorTiles& tileDesc = op.tileLayerDescriptor(); tileComposer->UseTiledLayerBuffer(this, tileDesc); break; } case CompositableOperation::TOpRemoveTexture: { const OpRemoveTexture& op = aEdit.get_OpRemoveTexture(); CompositableHost* compositable = AsCompositable(op); RefPtr<TextureHost> tex = TextureHost::AsTextureHost(op.textureParent()); MOZ_ASSERT(tex.get()); compositable->RemoveTextureHost(tex); // return texure data to client if necessary ReturnTextureDataIfNecessary(compositable, replyv, op.compositableParent()); break; } case CompositableOperation::TOpUseTexture: { const OpUseTexture& op = aEdit.get_OpUseTexture(); CompositableHost* compositable = AsCompositable(op); RefPtr<TextureHost> tex = TextureHost::AsTextureHost(op.textureParent()); MOZ_ASSERT(tex.get()); compositable->UseTextureHost(tex); if (IsAsync()) { ScheduleComposition(op); // Async layer updates don't trigger invalidation, manually tell the layer // that its content have changed. if (compositable->GetLayer()) { compositable->GetLayer()->SetInvalidRectToVisibleRegion(); } } // return texure data to client if necessary ReturnTextureDataIfNecessary(compositable, replyv, op.compositableParent()); break; } case CompositableOperation::TOpUseComponentAlphaTextures: { const OpUseComponentAlphaTextures& op = aEdit.get_OpUseComponentAlphaTextures(); CompositableHost* compositable = AsCompositable(op); RefPtr<TextureHost> texOnBlack = TextureHost::AsTextureHost(op.textureOnBlackParent()); RefPtr<TextureHost> texOnWhite = TextureHost::AsTextureHost(op.textureOnWhiteParent()); MOZ_ASSERT(texOnBlack && texOnWhite); compositable->UseComponentAlphaTextures(texOnBlack, texOnWhite); if (IsAsync()) { ScheduleComposition(op); } // return texure data to client if necessary ReturnTextureDataIfNecessary(compositable, replyv, op.compositableParent()); break; } case CompositableOperation::TOpUpdateTexture: { const OpUpdateTexture& op = aEdit.get_OpUpdateTexture(); RefPtr<TextureHost> texture = TextureHost::AsTextureHost(op.textureParent()); MOZ_ASSERT(texture); texture->Updated(op.region().type() == MaybeRegion::TnsIntRegion ? &op.region().get_nsIntRegion() : nullptr); // no region means invalidate the entire surface break; } default: { MOZ_ASSERT(false, "bad type"); } } return true; }
bool CompositableParentManager::ReceiveCompositableUpdate(const CompositableOperation& aEdit, EditReplyVector& replyv) { switch (aEdit.type()) { case CompositableOperation::TOpPaintTextureRegion: { MOZ_LAYERS_LOG(("[ParentSide] Paint PaintedLayer")); const OpPaintTextureRegion& op = aEdit.get_OpPaintTextureRegion(); CompositableHost* compositable = AsCompositable(op); Layer* layer = compositable->GetLayer(); if (!layer || layer->GetType() != Layer::TYPE_PAINTED) { return false; } PaintedLayerComposite* thebes = static_cast<PaintedLayerComposite*>(layer); const ThebesBufferData& bufferData = op.bufferData(); RenderTraceInvalidateStart(thebes, "FF00FF", op.updatedRegion().GetBounds()); nsIntRegion frontUpdatedRegion; if (!compositable->UpdateThebes(bufferData, op.updatedRegion(), thebes->GetValidRegion(), &frontUpdatedRegion)) { return false; } replyv.push_back( OpContentBufferSwap(op.compositableParent(), nullptr, frontUpdatedRegion)); RenderTraceInvalidateEnd(thebes, "FF00FF"); break; } case CompositableOperation::TOpUseTiledLayerBuffer: { MOZ_LAYERS_LOG(("[ParentSide] Paint TiledLayerBuffer")); const OpUseTiledLayerBuffer& op = aEdit.get_OpUseTiledLayerBuffer(); TiledContentHost* compositable = AsCompositable(op)->AsTiledContentHost(); NS_ASSERTION(compositable, "The compositable is not tiled"); const SurfaceDescriptorTiles& tileDesc = op.tileLayerDescriptor(); bool success = compositable->UseTiledLayerBuffer(this, tileDesc); if (!success) { return false; } break; } case CompositableOperation::TOpRemoveTexture: { const OpRemoveTexture& op = aEdit.get_OpRemoveTexture(); CompositableHost* compositable = AsCompositable(op); RefPtr<TextureHost> tex = TextureHost::AsTextureHost(op.textureParent()); MOZ_ASSERT(tex.get()); compositable->RemoveTextureHost(tex); // send FenceHandle if present. SendFenceHandleIfPresent(op.textureParent(), compositable); break; } case CompositableOperation::TOpRemoveTextureAsync: { const OpRemoveTextureAsync& op = aEdit.get_OpRemoveTextureAsync(); CompositableHost* compositable = AsCompositable(op); RefPtr<TextureHost> tex = TextureHost::AsTextureHost(op.textureParent()); MOZ_ASSERT(tex.get()); compositable->RemoveTextureHost(tex); if (!IsAsync() && ImageBridgeParent::GetInstance(GetChildProcessId())) { // send FenceHandle if present via ImageBridge. ImageBridgeParent::AppendDeliverFenceMessage( GetChildProcessId(), op.holderId(), op.transactionId(), op.textureParent(), compositable); // If the message is recievied via PLayerTransaction, // Send message back via PImageBridge. ImageBridgeParent::ReplyRemoveTexture( GetChildProcessId(), OpReplyRemoveTexture(op.holderId(), op.transactionId())); } else { // send FenceHandle if present. SendFenceHandleIfPresent(op.textureParent(), compositable); ReplyRemoveTexture(OpReplyRemoveTexture(op.holderId(), op.transactionId())); } break; } case CompositableOperation::TOpUseTexture: { const OpUseTexture& op = aEdit.get_OpUseTexture(); CompositableHost* compositable = AsCompositable(op); nsAutoTArray<CompositableHost::TimedTexture,4> textures; for (auto& timedTexture : op.textures()) { CompositableHost::TimedTexture* t = textures.AppendElement(); t->mTexture = TextureHost::AsTextureHost(timedTexture.textureParent()); MOZ_ASSERT(t->mTexture); t->mTimeStamp = timedTexture.timeStamp(); t->mPictureRect = timedTexture.picture(); t->mFrameID = timedTexture.frameID(); t->mProducerID = timedTexture.producerID(); MOZ_ASSERT(ValidatePictureRect(t->mTexture->GetSize(), t->mPictureRect)); MaybeFence maybeFence = timedTexture.fence(); if (maybeFence.type() == MaybeFence::TFenceHandle) { FenceHandle fence = maybeFence.get_FenceHandle(); if (fence.IsValid()) { t->mTexture->SetAcquireFenceHandle(fence); } } } compositable->UseTextureHost(textures); if (IsAsync() && compositable->GetLayer()) { ScheduleComposition(op); } break; } case CompositableOperation::TOpUseComponentAlphaTextures: { const OpUseComponentAlphaTextures& op = aEdit.get_OpUseComponentAlphaTextures(); CompositableHost* compositable = AsCompositable(op); RefPtr<TextureHost> texOnBlack = TextureHost::AsTextureHost(op.textureOnBlackParent()); RefPtr<TextureHost> texOnWhite = TextureHost::AsTextureHost(op.textureOnWhiteParent()); MOZ_ASSERT(texOnBlack && texOnWhite); compositable->UseComponentAlphaTextures(texOnBlack, texOnWhite); if (IsAsync()) { ScheduleComposition(op); } break; } #ifdef MOZ_WIDGET_GONK case CompositableOperation::TOpUseOverlaySource: { const OpUseOverlaySource& op = aEdit.get_OpUseOverlaySource(); CompositableHost* compositable = AsCompositable(op); MOZ_ASSERT(compositable->GetType() == CompositableType::IMAGE_OVERLAY, "Invalid operation!"); if (!ValidatePictureRect(op.overlay().size(), op.picture())) { return false; } compositable->UseOverlaySource(op.overlay(), op.picture()); break; } #endif default: { MOZ_ASSERT(false, "bad type"); } } return true; }
bool CompositableParentManager::ReceiveCompositableUpdate(const CompositableOperation& aEdit, EditReplyVector& replyv) { switch (aEdit.type()) { case CompositableOperation::TOpCreatedIncrementalTexture: { MOZ_LAYERS_LOG(("[ParentSide] Created texture")); const OpCreatedIncrementalTexture& op = aEdit.get_OpCreatedIncrementalTexture(); CompositableHost* compositable = AsCompositable(op); bool success = compositable->CreatedIncrementalTexture(this, op.textureInfo(), op.bufferRect()); if (!success) { return false; } break; } case CompositableOperation::TOpPaintTextureRegion: { MOZ_LAYERS_LOG(("[ParentSide] Paint ThebesLayer")); const OpPaintTextureRegion& op = aEdit.get_OpPaintTextureRegion(); CompositableHost* compositable = AsCompositable(op); Layer* layer = compositable->GetLayer(); if (!layer || layer->GetType() != Layer::TYPE_THEBES) { return false; } ThebesLayerComposite* thebes = static_cast<ThebesLayerComposite*>(layer); const ThebesBufferData& bufferData = op.bufferData(); RenderTraceInvalidateStart(thebes, "FF00FF", op.updatedRegion().GetBounds()); nsIntRegion frontUpdatedRegion; if (!compositable->UpdateThebes(bufferData, op.updatedRegion(), thebes->GetValidRegion(), &frontUpdatedRegion)) { return false; } replyv.push_back( OpContentBufferSwap(op.compositableParent(), nullptr, frontUpdatedRegion)); RenderTraceInvalidateEnd(thebes, "FF00FF"); // return texure data to client if necessary ReturnTextureDataIfNecessary(compositable, replyv, op.compositableParent()); break; } case CompositableOperation::TOpPaintTextureIncremental: { MOZ_LAYERS_LOG(("[ParentSide] Paint ThebesLayer")); const OpPaintTextureIncremental& op = aEdit.get_OpPaintTextureIncremental(); CompositableHost* compositable = AsCompositable(op); SurfaceDescriptor desc = op.image(); compositable->UpdateIncremental(op.textureId(), desc, op.updatedRegion(), op.bufferRect(), op.bufferRotation()); break; } case CompositableOperation::TOpUpdatePictureRect: { const OpUpdatePictureRect& op = aEdit.get_OpUpdatePictureRect(); CompositableHost* compositable = AsCompositable(op); MOZ_ASSERT(compositable); compositable->SetPictureRect(op.picture()); break; } case CompositableOperation::TOpUseTiledLayerBuffer: { MOZ_LAYERS_LOG(("[ParentSide] Paint TiledLayerBuffer")); const OpUseTiledLayerBuffer& op = aEdit.get_OpUseTiledLayerBuffer(); CompositableHost* compositable = AsCompositable(op); TiledLayerComposer* tileComposer = compositable->AsTiledLayerComposer(); NS_ASSERTION(tileComposer, "compositable is not a tile composer"); const SurfaceDescriptorTiles& tileDesc = op.tileLayerDescriptor(); tileComposer->UseTiledLayerBuffer(this, tileDesc); break; } case CompositableOperation::TOpRemoveTexture: { const OpRemoveTexture& op = aEdit.get_OpRemoveTexture(); CompositableHost* compositable = AsCompositable(op); RefPtr<TextureHost> tex = TextureHost::AsTextureHost(op.textureParent()); MOZ_ASSERT(tex.get()); compositable->RemoveTextureHost(tex); // return texure data to client if necessary ReturnTextureDataIfNecessary(compositable, replyv, op.compositableParent()); break; } case CompositableOperation::TOpUseTexture: { const OpUseTexture& op = aEdit.get_OpUseTexture(); CompositableHost* compositable = AsCompositable(op); RefPtr<TextureHost> tex = TextureHost::AsTextureHost(op.textureParent()); MOZ_ASSERT(tex.get()); compositable->UseTextureHost(tex); if (IsAsync()) { ScheduleComposition(op); // Async layer updates don't trigger invalidation, manually tell the layer // that its content have changed. if (compositable->GetLayer()) { compositable->GetLayer()->SetInvalidRectToVisibleRegion(); } } // return texure data to client if necessary ReturnTextureDataIfNecessary(compositable, replyv, op.compositableParent()); break; } case CompositableOperation::TOpUseComponentAlphaTextures: { const OpUseComponentAlphaTextures& op = aEdit.get_OpUseComponentAlphaTextures(); CompositableHost* compositable = AsCompositable(op); RefPtr<TextureHost> texOnBlack = TextureHost::AsTextureHost(op.textureOnBlackParent()); RefPtr<TextureHost> texOnWhite = TextureHost::AsTextureHost(op.textureOnWhiteParent()); MOZ_ASSERT(texOnBlack && texOnWhite); compositable->UseComponentAlphaTextures(texOnBlack, texOnWhite); if (IsAsync()) { ScheduleComposition(op); } // return texure data to client if necessary ReturnTextureDataIfNecessary(compositable, replyv, op.compositableParent()); break; } case CompositableOperation::TOpUpdateTexture: { const OpUpdateTexture& op = aEdit.get_OpUpdateTexture(); RefPtr<TextureHost> texture = TextureHost::AsTextureHost(op.textureParent()); MOZ_ASSERT(texture); texture->Updated(op.region().type() == MaybeRegion::TnsIntRegion ? &op.region().get_nsIntRegion() : nullptr); // no region means invalidate the entire surface break; } default: { MOZ_ASSERT(false, "bad type"); } } return true; }