Bug 927349 part 10 - Record the time when animations are ready to start; r=jwatt
[gecko.git] / gfx / layers / client / ClientLayerManager.cpp
blob6481a75c9d5095e6c94b18a4861e7635873b498a
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 * This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include "ClientLayerManager.h"
7 #include "GeckoProfiler.h" // for PROFILER_LABEL
8 #include "gfxPrefs.h" // for gfxPrefs::LayersTile...
9 #include "mozilla/Assertions.h" // for MOZ_ASSERT, etc
10 #include "mozilla/Hal.h"
11 #include "mozilla/dom/ScreenOrientation.h" // for ScreenOrientation
12 #include "mozilla/dom/TabChild.h" // for TabChild
13 #include "mozilla/hal_sandbox/PHal.h" // for ScreenConfiguration
14 #include "mozilla/layers/CompositableClient.h"
15 #include "mozilla/layers/CompositorChild.h" // for CompositorChild
16 #include "mozilla/layers/ContentClient.h"
17 #include "mozilla/layers/ISurfaceAllocator.h"
18 #include "mozilla/layers/LayersMessages.h" // for EditReply, etc
19 #include "mozilla/layers/LayersSurfaces.h" // for SurfaceDescriptor
20 #include "mozilla/layers/PLayerChild.h" // for PLayerChild
21 #include "mozilla/layers/LayerTransactionChild.h"
22 #include "mozilla/layers/TextureClientPool.h" // for TextureClientPool
23 #include "ClientReadbackLayer.h" // for ClientReadbackLayer
24 #include "nsAString.h"
25 #include "nsIWidget.h" // for nsIWidget
26 #include "nsIWidgetListener.h"
27 #include "nsTArray.h" // for AutoInfallibleTArray
28 #include "nsXULAppAPI.h" // for XRE_GetProcessType, etc
29 #include "TiledLayerBuffer.h"
30 #include "mozilla/dom/WindowBinding.h" // for Overfill Callback
31 #include "FrameLayerBuilder.h" // for FrameLayerbuilder
32 #include "gfxPrefs.h"
33 #ifdef MOZ_WIDGET_ANDROID
34 #include "AndroidBridge.h"
35 #include "LayerMetricsWrapper.h"
36 #endif
38 namespace mozilla {
39 namespace layers {
41 using namespace mozilla::gfx;
43 void
44 ClientLayerManager::MemoryPressureObserver::Destroy()
46 UnregisterMemoryPressureEvent();
47 mClientLayerManager = nullptr;
50 NS_IMETHODIMP
51 ClientLayerManager::MemoryPressureObserver::Observe(nsISupports* aSubject,
52 const char* aTopic,
53 const char16_t* aSomeData)
55 if (!mClientLayerManager || strcmp(aTopic, "memory-pressure")) {
56 return NS_OK;
59 mClientLayerManager->HandleMemoryPressure();
60 return NS_OK;
63 void
64 ClientLayerManager::MemoryPressureObserver::RegisterMemoryPressureEvent()
66 nsCOMPtr<nsIObserverService> observerService =
67 mozilla::services::GetObserverService();
69 MOZ_ASSERT(observerService);
71 if (observerService) {
72 observerService->AddObserver(this, "memory-pressure", false);
76 void
77 ClientLayerManager::MemoryPressureObserver::UnregisterMemoryPressureEvent()
79 nsCOMPtr<nsIObserverService> observerService =
80 mozilla::services::GetObserverService();
82 if (observerService) {
83 observerService->RemoveObserver(this, "memory-pressure");
87 NS_IMPL_ISUPPORTS(ClientLayerManager::MemoryPressureObserver, nsIObserver)
89 ClientLayerManager::ClientLayerManager(nsIWidget* aWidget)
90 : mPhase(PHASE_NONE)
91 , mWidget(aWidget)
92 , mLatestTransactionId(0)
93 , mTargetRotation(ROTATION_0)
94 , mRepeatTransaction(false)
95 , mIsRepeatTransaction(false)
96 , mTransactionIncomplete(false)
97 , mCompositorMightResample(false)
98 , mNeedsComposite(false)
99 , mPaintSequenceNumber(0)
100 , mForwarder(new ShadowLayerForwarder)
102 MOZ_COUNT_CTOR(ClientLayerManager);
103 mMemoryPressureObserver = new MemoryPressureObserver(this);
106 ClientLayerManager::~ClientLayerManager()
108 if (mTransactionIdAllocator) {
109 DidComposite(mLatestTransactionId);
111 mMemoryPressureObserver->Destroy();
112 ClearCachedResources();
113 // Stop receiveing AsyncParentMessage at Forwarder.
114 // After the call, the message is directly handled by LayerTransactionChild.
115 // Basically this function should be called in ShadowLayerForwarder's
116 // destructor. But when the destructor is triggered by
117 // CompositorChild::Destroy(), the destructor can not handle it correctly.
118 // See Bug 1000525.
119 mForwarder->StopReceiveAsyncParentMessge();
120 mRoot = nullptr;
122 MOZ_COUNT_DTOR(ClientLayerManager);
125 int32_t
126 ClientLayerManager::GetMaxTextureSize() const
128 return mForwarder->GetMaxTextureSize();
131 void
132 ClientLayerManager::SetDefaultTargetConfiguration(BufferMode aDoubleBuffering,
133 ScreenRotation aRotation)
135 mTargetRotation = aRotation;
138 void
139 ClientLayerManager::SetRoot(Layer* aLayer)
141 if (mRoot != aLayer) {
142 // Have to hold the old root and its children in order to
143 // maintain the same view of the layer tree in this process as
144 // the parent sees. Otherwise layers can be destroyed
145 // mid-transaction and bad things can happen (v. bug 612573)
146 if (mRoot) {
147 Hold(mRoot);
149 mForwarder->SetRoot(Hold(aLayer));
150 NS_ASSERTION(aLayer, "Root can't be null");
151 NS_ASSERTION(aLayer->Manager() == this, "Wrong manager");
152 NS_ASSERTION(InConstruction(), "Only allowed in construction phase");
153 mRoot = aLayer;
157 void
158 ClientLayerManager::Mutated(Layer* aLayer)
160 LayerManager::Mutated(aLayer);
162 NS_ASSERTION(InConstruction() || InDrawing(), "wrong phase");
163 mForwarder->Mutated(Hold(aLayer));
166 already_AddRefed<ReadbackLayer>
167 ClientLayerManager::CreateReadbackLayer()
169 nsRefPtr<ReadbackLayer> layer = new ClientReadbackLayer(this);
170 return layer.forget();
173 void
174 ClientLayerManager::BeginTransactionWithTarget(gfxContext* aTarget)
176 mInTransaction = true;
177 mTransactionStart = TimeStamp::Now();
179 #ifdef MOZ_LAYERS_HAVE_LOG
180 MOZ_LAYERS_LOG(("[----- BeginTransaction"));
181 Log();
182 #endif
184 NS_ASSERTION(!InTransaction(), "Nested transactions not allowed");
185 mPhase = PHASE_CONSTRUCTION;
187 NS_ABORT_IF_FALSE(mKeepAlive.IsEmpty(), "uncommitted txn?");
188 nsRefPtr<gfxContext> targetContext = aTarget;
190 // If the last transaction was incomplete (a failed DoEmptyTransaction),
191 // don't signal a new transaction to ShadowLayerForwarder. Carry on adding
192 // to the previous transaction.
193 dom::ScreenOrientation orientation;
194 if (dom::TabChild* window = mWidget->GetOwningTabChild()) {
195 orientation = window->GetOrientation();
196 } else {
197 hal::ScreenConfiguration currentConfig;
198 hal::GetCurrentScreenConfiguration(&currentConfig);
199 orientation = currentConfig.orientation();
201 nsIntRect targetBounds = mWidget->GetNaturalBounds();
202 targetBounds.x = targetBounds.y = 0;
203 mForwarder->BeginTransaction(targetBounds, mTargetRotation, orientation);
205 // If we're drawing on behalf of a context with async pan/zoom
206 // enabled, then the entire buffer of painted layers might be
207 // composited (including resampling) asynchronously before we get
208 // a chance to repaint, so we have to ensure that it's all valid
209 // and not rotated.
210 if (mWidget) {
211 if (dom::TabChild* window = mWidget->GetOwningTabChild()) {
212 mCompositorMightResample = window->IsAsyncPanZoomEnabled();
216 // If we have a non-default target, we need to let our shadow manager draw
217 // to it. This will happen at the end of the transaction.
218 if (aTarget && XRE_GetProcessType() == GeckoProcessType_Default) {
219 mShadowTarget = aTarget;
220 } else {
221 NS_ASSERTION(!aTarget,
222 "Content-process ClientLayerManager::BeginTransactionWithTarget not supported");
225 // If this is a new paint, increment the paint sequence number.
226 if (!mIsRepeatTransaction && gfxPrefs::APZTestLoggingEnabled()) {
227 ++mPaintSequenceNumber;
228 mApzTestData.StartNewPaint(mPaintSequenceNumber);
232 void
233 ClientLayerManager::BeginTransaction()
235 BeginTransactionWithTarget(nullptr);
238 bool
239 ClientLayerManager::EndTransactionInternal(DrawPaintedLayerCallback aCallback,
240 void* aCallbackData,
241 EndTransactionFlags)
243 PROFILER_LABEL("ClientLayerManager", "EndTransactionInternal",
244 js::ProfileEntry::Category::GRAPHICS);
246 #ifdef MOZ_LAYERS_HAVE_LOG
247 MOZ_LAYERS_LOG((" ----- (beginning paint)"));
248 Log();
249 #endif
250 profiler_tracing("Paint", "Rasterize", TRACING_INTERVAL_START);
252 NS_ASSERTION(InConstruction(), "Should be in construction phase");
253 mPhase = PHASE_DRAWING;
255 ClientLayer* root = ClientLayer::ToClientLayer(GetRoot());
257 mTransactionIncomplete = false;
259 // Apply pending tree updates before recomputing effective
260 // properties.
261 GetRoot()->ApplyPendingUpdatesToSubtree();
263 mPaintedLayerCallback = aCallback;
264 mPaintedLayerCallbackData = aCallbackData;
266 GetRoot()->ComputeEffectiveTransforms(Matrix4x4());
268 root->RenderLayer();
269 if (!mRepeatTransaction && !GetRoot()->GetInvalidRegion().IsEmpty()) {
270 GetRoot()->Mutated();
273 if (!mIsRepeatTransaction) {
274 mAnimationReadyTime = TimeStamp::Now();
277 mPaintedLayerCallback = nullptr;
278 mPaintedLayerCallbackData = nullptr;
280 // Go back to the construction phase if the transaction isn't complete.
281 // Layout will update the layer tree and call EndTransaction().
282 mPhase = mTransactionIncomplete ? PHASE_CONSTRUCTION : PHASE_NONE;
284 NS_ASSERTION(!aCallback || !mTransactionIncomplete,
285 "If callback is not null, transaction must be complete");
287 if (gfxPlatform::GetPlatform()->DidRenderingDeviceReset()) {
288 FrameLayerBuilder::InvalidateAllLayers(this);
291 return !mTransactionIncomplete;
294 void
295 ClientLayerManager::EndTransaction(DrawPaintedLayerCallback aCallback,
296 void* aCallbackData,
297 EndTransactionFlags aFlags)
299 if (mWidget) {
300 mWidget->PrepareWindowEffects();
302 EndTransactionInternal(aCallback, aCallbackData, aFlags);
303 ForwardTransaction(!(aFlags & END_NO_REMOTE_COMPOSITE));
305 if (mRepeatTransaction) {
306 mRepeatTransaction = false;
307 mIsRepeatTransaction = true;
308 BeginTransaction();
309 ClientLayerManager::EndTransaction(aCallback, aCallbackData, aFlags);
310 mIsRepeatTransaction = false;
311 } else {
312 MakeSnapshotIfRequired();
315 for (size_t i = 0; i < mTexturePools.Length(); i++) {
316 mTexturePools[i]->ReturnDeferredClients();
319 mInTransaction = false;
320 mTransactionStart = TimeStamp();
323 bool
324 ClientLayerManager::EndEmptyTransaction(EndTransactionFlags aFlags)
326 mInTransaction = false;
328 if (!mRoot) {
329 return false;
331 if (!EndTransactionInternal(nullptr, nullptr, aFlags)) {
332 // Return without calling ForwardTransaction. This leaves the
333 // ShadowLayerForwarder transaction open; the following
334 // EndTransaction will complete it.
335 return false;
337 if (mWidget) {
338 mWidget->PrepareWindowEffects();
340 ForwardTransaction(!(aFlags & END_NO_REMOTE_COMPOSITE));
341 MakeSnapshotIfRequired();
342 return true;
345 CompositorChild *
346 ClientLayerManager::GetRemoteRenderer()
348 if (!mWidget) {
349 return nullptr;
352 return mWidget->GetRemoteRenderer();
355 CompositorChild*
356 ClientLayerManager::GetCompositorChild()
358 if (XRE_GetProcessType() != GeckoProcessType_Default) {
359 return CompositorChild::Get();
361 return GetRemoteRenderer();
364 void
365 ClientLayerManager::Composite()
367 mForwarder->Composite();
370 void
371 ClientLayerManager::DidComposite(uint64_t aTransactionId)
373 MOZ_ASSERT(mWidget);
374 nsIWidgetListener *listener = mWidget->GetWidgetListener();
375 if (listener) {
376 listener->DidCompositeWindow();
378 listener = mWidget->GetAttachedWidgetListener();
379 if (listener) {
380 listener->DidCompositeWindow();
382 mTransactionIdAllocator->NotifyTransactionCompleted(aTransactionId);
385 void
386 ClientLayerManager::GetCompositorSideAPZTestData(APZTestData* aData) const
388 if (mForwarder->HasShadowManager()) {
389 if (!mForwarder->GetShadowManager()->SendGetAPZTestData(aData)) {
390 NS_WARNING("Call to PLayerTransactionChild::SendGetAPZTestData() failed");
395 float
396 ClientLayerManager::RequestProperty(const nsAString& aProperty)
398 if (mForwarder->HasShadowManager()) {
399 float value;
400 if (!mForwarder->GetShadowManager()->SendRequestProperty(nsString(aProperty), &value)) {
401 NS_WARNING("Call to PLayerTransactionChild::SendGetAPZTestData() failed");
403 return value;
405 return -1;
408 void
409 ClientLayerManager::StartNewRepaintRequest(SequenceNumber aSequenceNumber)
411 if (gfxPrefs::APZTestLoggingEnabled()) {
412 mApzTestData.StartNewRepaintRequest(aSequenceNumber);
416 bool
417 ClientLayerManager::RequestOverfill(mozilla::dom::OverfillCallback* aCallback)
419 MOZ_ASSERT(aCallback != nullptr);
420 MOZ_ASSERT(HasShadowManager(), "Request Overfill only supported on b2g for now");
422 if (HasShadowManager()) {
423 CompositorChild* child = GetRemoteRenderer();
424 NS_ASSERTION(child, "Could not get CompositorChild");
426 child->AddOverfillObserver(this);
427 child->SendRequestOverfill();
428 mOverfillCallbacks.AppendElement(aCallback);
431 return true;
434 void
435 ClientLayerManager::RunOverfillCallback(const uint32_t aOverfill)
437 for (size_t i = 0; i < mOverfillCallbacks.Length(); i++) {
438 ErrorResult error;
439 mOverfillCallbacks[i]->Call(aOverfill, error);
442 mOverfillCallbacks.Clear();
445 void
446 ClientLayerManager::MakeSnapshotIfRequired()
448 if (!mShadowTarget) {
449 return;
451 if (mWidget) {
452 if (CompositorChild* remoteRenderer = GetRemoteRenderer()) {
453 // The compositor doesn't draw to a different sized surface
454 // when there's a rotation. Instead we rotate the result
455 // when drawing into dt
456 nsIntRect outerBounds;
457 mWidget->GetBounds(outerBounds);
459 nsIntRect bounds = ToOutsideIntRect(mShadowTarget->GetClipExtents());
460 if (mTargetRotation) {
461 bounds = RotateRect(bounds, outerBounds, mTargetRotation);
464 SurfaceDescriptor inSnapshot;
465 if (!bounds.IsEmpty() &&
466 mForwarder->AllocSurfaceDescriptor(bounds.Size().ToIntSize(),
467 gfxContentType::COLOR_ALPHA,
468 &inSnapshot) &&
469 remoteRenderer->SendMakeSnapshot(inSnapshot, bounds)) {
470 RefPtr<DataSourceSurface> surf = GetSurfaceForDescriptor(inSnapshot);
471 DrawTarget* dt = mShadowTarget->GetDrawTarget();
473 Rect dstRect(bounds.x, bounds.y, bounds.width, bounds.height);
474 Rect srcRect(0, 0, bounds.width, bounds.height);
476 gfx::Matrix rotate = ComputeTransformForUnRotation(outerBounds, mTargetRotation);
478 gfx::Matrix oldMatrix = dt->GetTransform();
479 dt->SetTransform(oldMatrix * rotate);
480 dt->DrawSurface(surf, dstRect, srcRect,
481 DrawSurfaceOptions(),
482 DrawOptions(1.0f, CompositionOp::OP_OVER));
483 dt->SetTransform(oldMatrix);
485 mForwarder->DestroySharedSurface(&inSnapshot);
488 mShadowTarget = nullptr;
491 void
492 ClientLayerManager::FlushRendering()
494 if (mWidget) {
495 if (CompositorChild* remoteRenderer = mWidget->GetRemoteRenderer()) {
496 remoteRenderer->SendFlushRendering();
501 void
502 ClientLayerManager::SendInvalidRegion(const nsIntRegion& aRegion)
504 if (mWidget) {
505 if (CompositorChild* remoteRenderer = mWidget->GetRemoteRenderer()) {
506 remoteRenderer->SendNotifyRegionInvalidated(aRegion);
511 uint32_t
512 ClientLayerManager::StartFrameTimeRecording(int32_t aBufferSize)
514 CompositorChild* renderer = GetRemoteRenderer();
515 if (renderer) {
516 uint32_t startIndex;
517 renderer->SendStartFrameTimeRecording(aBufferSize, &startIndex);
518 return startIndex;
520 return -1;
523 void
524 ClientLayerManager::StopFrameTimeRecording(uint32_t aStartIndex,
525 nsTArray<float>& aFrameIntervals)
527 CompositorChild* renderer = GetRemoteRenderer();
528 if (renderer) {
529 renderer->SendStopFrameTimeRecording(aStartIndex, &aFrameIntervals);
533 void
534 ClientLayerManager::ForwardTransaction(bool aScheduleComposite)
536 if (mForwarder->GetSyncObject()) {
537 mForwarder->GetSyncObject()->FinalizeFrame();
540 mPhase = PHASE_FORWARD;
542 mLatestTransactionId = mTransactionIdAllocator->GetTransactionId();
543 TimeStamp transactionStart;
544 if (!mTransactionIdAllocator->GetTransactionStart().IsNull()) {
545 transactionStart = mTransactionIdAllocator->GetTransactionStart();
546 } else {
547 transactionStart = mTransactionStart;
550 // forward this transaction's changeset to our LayerManagerComposite
551 bool sent;
552 AutoInfallibleTArray<EditReply, 10> replies;
553 if (mForwarder->EndTransaction(&replies, mRegionToClear,
554 mLatestTransactionId, aScheduleComposite, mPaintSequenceNumber,
555 mIsRepeatTransaction, transactionStart, &sent)) {
556 for (nsTArray<EditReply>::size_type i = 0; i < replies.Length(); ++i) {
557 const EditReply& reply = replies[i];
559 switch (reply.type()) {
560 case EditReply::TOpContentBufferSwap: {
561 MOZ_LAYERS_LOG(("[LayersForwarder] DoubleBufferSwap"));
563 const OpContentBufferSwap& obs = reply.get_OpContentBufferSwap();
565 CompositableClient* compositable =
566 CompositableClient::FromIPDLActor(obs.compositableChild());
567 ContentClientRemote* contentClient =
568 static_cast<ContentClientRemote*>(compositable);
569 MOZ_ASSERT(contentClient);
571 contentClient->SwapBuffers(obs.frontUpdatedRegion());
573 break;
575 case EditReply::TOpTextureSwap: {
576 MOZ_LAYERS_LOG(("[LayersForwarder] TextureSwap"));
578 const OpTextureSwap& ots = reply.get_OpTextureSwap();
580 CompositableClient* compositable =
581 CompositableClient::FromIPDLActor(ots.compositableChild());
582 MOZ_ASSERT(compositable);
583 compositable->SetDescriptorFromReply(ots.textureId(), ots.image());
584 break;
586 case EditReply::TReturnReleaseFence: {
587 const ReturnReleaseFence& rep = reply.get_ReturnReleaseFence();
588 FenceHandle fence = rep.fence();
589 PTextureChild* child = rep.textureChild();
591 if (!fence.IsValid() || !child) {
592 break;
594 RefPtr<TextureClient> texture = TextureClient::AsTextureClient(child);
595 if (texture) {
596 texture->SetReleaseFenceHandle(fence);
598 break;
601 default:
602 NS_RUNTIMEABORT("not reached");
606 if (sent) {
607 mNeedsComposite = false;
609 } else if (HasShadowManager()) {
610 NS_WARNING("failed to forward Layers transaction");
613 if (!sent) {
614 // Clear the transaction id so that it doesn't get returned
615 // unless we forwarded to somewhere that doesn't actually
616 // have a compositor.
617 mTransactionIdAllocator->RevokeTransactionId(mLatestTransactionId);
620 mForwarder->RemoveTexturesIfNecessary();
621 mForwarder->SendPendingAsyncMessges();
622 mPhase = PHASE_NONE;
624 // this may result in Layers being deleted, which results in
625 // PLayer::Send__delete__() and DeallocShmem()
626 mKeepAlive.Clear();
629 ShadowableLayer*
630 ClientLayerManager::Hold(Layer* aLayer)
632 NS_ABORT_IF_FALSE(HasShadowManager(),
633 "top-level tree, no shadow tree to remote to");
635 ShadowableLayer* shadowable = ClientLayer::ToClientLayer(aLayer);
636 NS_ABORT_IF_FALSE(shadowable, "trying to remote an unshadowable layer");
638 mKeepAlive.AppendElement(aLayer);
639 return shadowable;
642 bool
643 ClientLayerManager::IsCompositingCheap()
645 // Whether compositing is cheap depends on the parent backend.
646 return mForwarder->mShadowManager &&
647 LayerManager::IsCompositingCheap(mForwarder->GetCompositorBackendType());
650 bool
651 ClientLayerManager::AreComponentAlphaLayersEnabled()
653 return GetCompositorBackendType() != LayersBackend::LAYERS_BASIC &&
654 LayerManager::AreComponentAlphaLayersEnabled();
657 void
658 ClientLayerManager::SetIsFirstPaint()
660 mForwarder->SetIsFirstPaint();
663 TextureClientPool*
664 ClientLayerManager::GetTexturePool(SurfaceFormat aFormat)
666 for (size_t i = 0; i < mTexturePools.Length(); i++) {
667 if (mTexturePools[i]->GetFormat() == aFormat) {
668 return mTexturePools[i];
672 mTexturePools.AppendElement(
673 new TextureClientPool(aFormat, IntSize(gfxPlatform::GetPlatform()->GetTileWidth(),
674 gfxPlatform::GetPlatform()->GetTileHeight()),
675 gfxPrefs::LayersTileMaxPoolSize(),
676 gfxPrefs::LayersTileShrinkPoolTimeout(),
677 mForwarder));
679 return mTexturePools.LastElement();
682 void
683 ClientLayerManager::ReturnTextureClientDeferred(TextureClient& aClient) {
684 GetTexturePool(aClient.GetFormat())->ReturnTextureClientDeferred(&aClient);
687 void
688 ClientLayerManager::ReturnTextureClient(TextureClient& aClient) {
689 GetTexturePool(aClient.GetFormat())->ReturnTextureClient(&aClient);
692 void
693 ClientLayerManager::ReportClientLost(TextureClient& aClient) {
694 GetTexturePool(aClient.GetFormat())->ReportClientLost();
697 void
698 ClientLayerManager::ClearCachedResources(Layer* aSubtree)
700 MOZ_ASSERT(!HasShadowManager() || !aSubtree);
701 mForwarder->ClearCachedResources();
702 if (aSubtree) {
703 ClearLayer(aSubtree);
704 } else if (mRoot) {
705 ClearLayer(mRoot);
707 for (size_t i = 0; i < mTexturePools.Length(); i++) {
708 mTexturePools[i]->Clear();
712 void
713 ClientLayerManager::HandleMemoryPressure()
715 for (size_t i = 0; i < mTexturePools.Length(); i++) {
716 mTexturePools[i]->ShrinkToMinimumSize();
720 void
721 ClientLayerManager::ClearLayer(Layer* aLayer)
723 ClientLayer::ToClientLayer(aLayer)->ClearCachedResources();
724 for (Layer* child = aLayer->GetFirstChild(); child;
725 child = child->GetNextSibling()) {
726 ClearLayer(child);
730 void
731 ClientLayerManager::GetBackendName(nsAString& aName)
733 switch (mForwarder->GetCompositorBackendType()) {
734 case LayersBackend::LAYERS_BASIC: aName.AssignLiteral("Basic"); return;
735 case LayersBackend::LAYERS_OPENGL: aName.AssignLiteral("OpenGL"); return;
736 case LayersBackend::LAYERS_D3D9: aName.AssignLiteral("Direct3D 9"); return;
737 case LayersBackend::LAYERS_D3D10: aName.AssignLiteral("Direct3D 10"); return;
738 case LayersBackend::LAYERS_D3D11: aName.AssignLiteral("Direct3D 11"); return;
739 default: NS_RUNTIMEABORT("Invalid backend");
743 bool
744 ClientLayerManager::ProgressiveUpdateCallback(bool aHasPendingNewThebesContent,
745 FrameMetrics& aMetrics,
746 bool aDrawingCritical)
748 #ifdef MOZ_WIDGET_ANDROID
749 MOZ_ASSERT(aMetrics.IsScrollable());
750 // This is derived from the code in
751 // gfx/layers/ipc/CompositorParent.cpp::TransformShadowTree.
752 CSSToLayerScale paintScale = aMetrics.LayersPixelsPerCSSPixel();
753 const CSSRect& metricsDisplayPort =
754 (aDrawingCritical && !aMetrics.mCriticalDisplayPort.IsEmpty()) ?
755 aMetrics.mCriticalDisplayPort : aMetrics.mDisplayPort;
756 LayerRect displayPort = (metricsDisplayPort + aMetrics.GetScrollOffset()) * paintScale;
758 ParentLayerPoint scrollOffset;
759 CSSToParentLayerScale zoom;
760 bool ret = AndroidBridge::Bridge()->ProgressiveUpdateCallback(
761 aHasPendingNewThebesContent, displayPort, paintScale.scale, aDrawingCritical,
762 scrollOffset, zoom);
763 aMetrics.SetScrollOffset(scrollOffset / zoom);
764 aMetrics.SetZoom(zoom);
765 return ret;
766 #else
767 return false;
768 #endif
771 ClientLayer::~ClientLayer()
773 if (HasShadow()) {
774 PLayerChild::Send__delete__(GetShadow());
776 MOZ_COUNT_DTOR(ClientLayer);
779 } // layers
780 } // mozilla