void BasicShadowableThebesLayer::PaintBuffer(gfxContext* aContext, const nsIntRegion& aRegionToDraw, const nsIntRegion& aExtendedRegionToDraw, const nsIntRegion& aRegionToInvalidate, bool aDidSelfCopy, LayerManager::DrawThebesLayerCallback aCallback, void* aCallbackData) { ContentClientRemote* contentClientRemote = static_cast<ContentClientRemote*>(mContentClient.get()); MOZ_ASSERT(contentClientRemote->GetIPDLActor() || !HasShadow()); // NB: this just throws away the entire valid region if there are // too many rects. mValidRegion.SimplifyInward(8); Base::PaintBuffer(aContext, aRegionToDraw, aExtendedRegionToDraw, aRegionToInvalidate, aDidSelfCopy, aCallback, aCallbackData); if (!HasShadow() || BasicManager()->IsTransactionIncomplete()) { return; } // Hold(this) ensures this layer is kept alive through the current transaction // The ContentClient assumes this layer is kept alive (e.g., in CreateBuffer, // DestroyThebesBuffer), so deleting this Hold for whatever reason will break things. BasicManager()->Hold(this); contentClientRemote->Updated(aRegionToDraw, mVisibleRegion, aDidSelfCopy); }
void ClientThebesLayer::PaintBuffer(gfxContext* aContext, const nsIntRegion& aRegionToDraw, const nsIntRegion& aExtendedRegionToDraw, const nsIntRegion& aRegionToInvalidate, bool aDidSelfCopy, DrawRegionClip aClip) { ContentClientRemote* contentClientRemote = static_cast<ContentClientRemote*>(mContentClient.get()); MOZ_ASSERT(contentClientRemote->GetIPDLActor()); // NB: this just throws away the entire valid region if there are // too many rects. mValidRegion.SimplifyInward(8); if (!ClientManager()->GetThebesLayerCallback()) { ClientManager()->SetTransactionIncomplete(); return; } ClientManager()->GetThebesLayerCallback()(this, aContext, aExtendedRegionToDraw, aClip, aRegionToInvalidate, ClientManager()->GetThebesLayerCallbackData()); // Everything that's visible has been validated. Do this instead of just // OR-ing with aRegionToDraw, since that can lead to a very complex region // here (OR doesn't automatically simplify to the simplest possible // representation of a region.) nsIntRegion tmp; tmp.Or(mVisibleRegion, aExtendedRegionToDraw); mValidRegion.Or(mValidRegion, tmp); // Hold(this) ensures this layer is kept alive through the current transaction // The ContentClient assumes this layer is kept alive (e.g., in CreateBuffer, // DestroyThebesBuffer), so deleting this Hold for whatever reason will break things. ClientManager()->Hold(this); contentClientRemote->Updated(aRegionToDraw, mVisibleRegion, aDidSelfCopy); }
void ClientPaintedLayer::PaintThebes() { PROFILER_LABEL("ClientPaintedLayer", "PaintThebes", js::ProfileEntry::Category::GRAPHICS); NS_ASSERTION(ClientManager()->InDrawing(), "Can only draw in drawing phase"); uint32_t flags = RotatedContentBuffer::PAINT_CAN_DRAW_ROTATED; #ifndef MOZ_IGNORE_PAINT_WILL_RESAMPLE if (ClientManager()->CompositorMightResample()) { flags |= RotatedContentBuffer::PAINT_WILL_RESAMPLE; } if (!(flags & RotatedContentBuffer::PAINT_WILL_RESAMPLE)) { if (MayResample()) { flags |= RotatedContentBuffer::PAINT_WILL_RESAMPLE; } } #endif PaintState state = mContentClient->BeginPaintBuffer(this, flags); mValidRegion.Sub(mValidRegion, state.mRegionToInvalidate); if (!state.mRegionToDraw.IsEmpty() && !ClientManager()->GetPaintedLayerCallback()) { ClientManager()->SetTransactionIncomplete(); return; } // The area that became invalid and is visible needs to be repainted // (this could be the whole visible area if our buffer switched // from RGB to RGBA, because we might need to repaint with // subpixel AA) state.mRegionToInvalidate.And(state.mRegionToInvalidate, GetEffectiveVisibleRegion()); bool didUpdate = false; RotatedContentBuffer::DrawIterator iter; while (DrawTarget* target = mContentClient->BorrowDrawTargetForPainting(state, &iter)) { SetAntialiasingFlags(this, target); nsRefPtr<gfxContext> ctx = gfxContext::ContextForDrawTarget(target); ClientManager()->GetPaintedLayerCallback()(this, ctx, iter.mDrawRegion, state.mClip, state.mRegionToInvalidate, ClientManager()->GetPaintedLayerCallbackData()); ctx = nullptr; mContentClient->ReturnDrawTargetToBuffer(target); didUpdate = true; } if (didUpdate) { Mutated(); mValidRegion.Or(mValidRegion, state.mRegionToDraw); ContentClientRemote* contentClientRemote = static_cast<ContentClientRemote*>(mContentClient.get()); MOZ_ASSERT(contentClientRemote->GetIPDLActor()); // Hold(this) ensures this layer is kept alive through the current transaction // The ContentClient assumes this layer is kept alive (e.g., in CreateBuffer), // so deleting this Hold for whatever reason will break things. ClientManager()->Hold(this); contentClientRemote->Updated(state.mRegionToDraw, mVisibleRegion, state.mDidSelfCopy); } }
void WebRenderPaintedLayer::PaintThebes(nsTArray<ReadbackProcessor::Update>* aReadbackUpdates) { PROFILER_LABEL("WebRenderPaintedLayer", "PaintThebes", js::ProfileEntry::Category::GRAPHICS); mContentClient->BeginPaint(); uint32_t flags = RotatedContentBuffer::PAINT_CAN_DRAW_ROTATED; PaintState state = mContentClient->BeginPaintBuffer(this, flags); mValidRegion.Sub(mValidRegion, state.mRegionToInvalidate); if (!state.mRegionToDraw.IsEmpty() && !Manager()->GetPaintedLayerCallback()) { return; } // The area that became invalid and is visible needs to be repainted // (this could be the whole visible area if our buffer switched // from RGB to RGBA, because we might need to repaint with // subpixel AA) state.mRegionToInvalidate.And(state.mRegionToInvalidate, GetLocalVisibleRegion().ToUnknownRegion()); bool didUpdate = false; RotatedContentBuffer::DrawIterator iter; while (DrawTarget* target = mContentClient->BorrowDrawTargetForPainting(state, &iter)) { if (!target || !target->IsValid()) { if (target) { mContentClient->ReturnDrawTargetToBuffer(target); } continue; } SetAntialiasingFlags(this, target); RefPtr<gfxContext> ctx = gfxContext::CreatePreservingTransformOrNull(target); MOZ_ASSERT(ctx); // already checked the target above Manager()->GetPaintedLayerCallback()(this, ctx, iter.mDrawRegion, iter.mDrawRegion, state.mClip, state.mRegionToInvalidate, Manager()->GetPaintedLayerCallbackData()); ctx = nullptr; mContentClient->ReturnDrawTargetToBuffer(target); didUpdate = true; } mContentClient->EndPaint(aReadbackUpdates); if (didUpdate) { Mutated(); // XXX It will cause reftests failures. See Bug 1340798. //mValidRegion.Or(mValidRegion, state.mRegionToDraw); ContentClientRemote* contentClientRemote = static_cast<ContentClientRemote*>(mContentClient.get()); // Hold(this) ensures this layer is kept alive through the current transaction // The ContentClient assumes this layer is kept alive (e.g., in CreateBuffer), // so deleting this Hold for whatever reason will break things. Manager()->Hold(this); contentClientRemote->Updated(state.mRegionToDraw, mVisibleRegion.ToUnknownRegion(), state.mDidSelfCopy); } }