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
33 #ifdef MOZ_WIDGET_ANDROID
34 #include "AndroidBridge.h"
35 #include "LayerMetricsWrapper.h"
41 using namespace mozilla::gfx
;
44 ClientLayerManager::MemoryPressureObserver::Destroy()
46 UnregisterMemoryPressureEvent();
47 mClientLayerManager
= nullptr;
51 ClientLayerManager::MemoryPressureObserver::Observe(nsISupports
* aSubject
,
53 const char16_t
* aSomeData
)
55 if (!mClientLayerManager
|| strcmp(aTopic
, "memory-pressure")) {
59 mClientLayerManager
->HandleMemoryPressure();
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);
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
)
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.
119 mForwarder
->StopReceiveAsyncParentMessge();
122 MOZ_COUNT_DTOR(ClientLayerManager
);
126 ClientLayerManager::GetMaxTextureSize() const
128 return mForwarder
->GetMaxTextureSize();
132 ClientLayerManager::SetDefaultTargetConfiguration(BufferMode aDoubleBuffering
,
133 ScreenRotation aRotation
)
135 mTargetRotation
= aRotation
;
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)
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");
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();
174 ClientLayerManager::BeginTransactionWithTarget(gfxContext
* aTarget
)
176 mInTransaction
= true;
177 mTransactionStart
= TimeStamp::Now();
179 #ifdef MOZ_LAYERS_HAVE_LOG
180 MOZ_LAYERS_LOG(("[----- BeginTransaction"));
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();
197 hal::ScreenConfiguration currentConfig
;
198 hal::GetCurrentScreenConfiguration(¤tConfig
);
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
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
;
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
);
233 ClientLayerManager::BeginTransaction()
235 BeginTransactionWithTarget(nullptr);
239 ClientLayerManager::EndTransactionInternal(DrawPaintedLayerCallback aCallback
,
243 PROFILER_LABEL("ClientLayerManager", "EndTransactionInternal",
244 js::ProfileEntry::Category::GRAPHICS
);
246 #ifdef MOZ_LAYERS_HAVE_LOG
247 MOZ_LAYERS_LOG((" ----- (beginning paint)"));
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
261 GetRoot()->ApplyPendingUpdatesToSubtree();
263 mPaintedLayerCallback
= aCallback
;
264 mPaintedLayerCallbackData
= aCallbackData
;
266 GetRoot()->ComputeEffectiveTransforms(Matrix4x4());
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
;
295 ClientLayerManager::EndTransaction(DrawPaintedLayerCallback aCallback
,
297 EndTransactionFlags aFlags
)
300 mWidget
->PrepareWindowEffects();
302 EndTransactionInternal(aCallback
, aCallbackData
, aFlags
);
303 ForwardTransaction(!(aFlags
& END_NO_REMOTE_COMPOSITE
));
305 if (mRepeatTransaction
) {
306 mRepeatTransaction
= false;
307 mIsRepeatTransaction
= true;
309 ClientLayerManager::EndTransaction(aCallback
, aCallbackData
, aFlags
);
310 mIsRepeatTransaction
= false;
312 MakeSnapshotIfRequired();
315 for (size_t i
= 0; i
< mTexturePools
.Length(); i
++) {
316 mTexturePools
[i
]->ReturnDeferredClients();
319 mInTransaction
= false;
320 mTransactionStart
= TimeStamp();
324 ClientLayerManager::EndEmptyTransaction(EndTransactionFlags aFlags
)
326 mInTransaction
= 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.
338 mWidget
->PrepareWindowEffects();
340 ForwardTransaction(!(aFlags
& END_NO_REMOTE_COMPOSITE
));
341 MakeSnapshotIfRequired();
346 ClientLayerManager::GetRemoteRenderer()
352 return mWidget
->GetRemoteRenderer();
356 ClientLayerManager::GetCompositorChild()
358 if (XRE_GetProcessType() != GeckoProcessType_Default
) {
359 return CompositorChild::Get();
361 return GetRemoteRenderer();
365 ClientLayerManager::Composite()
367 mForwarder
->Composite();
371 ClientLayerManager::DidComposite(uint64_t aTransactionId
)
374 nsIWidgetListener
*listener
= mWidget
->GetWidgetListener();
376 listener
->DidCompositeWindow();
378 listener
= mWidget
->GetAttachedWidgetListener();
380 listener
->DidCompositeWindow();
382 mTransactionIdAllocator
->NotifyTransactionCompleted(aTransactionId
);
386 ClientLayerManager::GetCompositorSideAPZTestData(APZTestData
* aData
) const
388 if (mForwarder
->HasShadowManager()) {
389 if (!mForwarder
->GetShadowManager()->SendGetAPZTestData(aData
)) {
390 NS_WARNING("Call to PLayerTransactionChild::SendGetAPZTestData() failed");
396 ClientLayerManager::RequestProperty(const nsAString
& aProperty
)
398 if (mForwarder
->HasShadowManager()) {
400 if (!mForwarder
->GetShadowManager()->SendRequestProperty(nsString(aProperty
), &value
)) {
401 NS_WARNING("Call to PLayerTransactionChild::SendGetAPZTestData() failed");
409 ClientLayerManager::StartNewRepaintRequest(SequenceNumber aSequenceNumber
)
411 if (gfxPrefs::APZTestLoggingEnabled()) {
412 mApzTestData
.StartNewRepaintRequest(aSequenceNumber
);
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
);
435 ClientLayerManager::RunOverfillCallback(const uint32_t aOverfill
)
437 for (size_t i
= 0; i
< mOverfillCallbacks
.Length(); i
++) {
439 mOverfillCallbacks
[i
]->Call(aOverfill
, error
);
442 mOverfillCallbacks
.Clear();
446 ClientLayerManager::MakeSnapshotIfRequired()
448 if (!mShadowTarget
) {
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
,
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;
492 ClientLayerManager::FlushRendering()
495 if (CompositorChild
* remoteRenderer
= mWidget
->GetRemoteRenderer()) {
496 remoteRenderer
->SendFlushRendering();
502 ClientLayerManager::SendInvalidRegion(const nsIntRegion
& aRegion
)
505 if (CompositorChild
* remoteRenderer
= mWidget
->GetRemoteRenderer()) {
506 remoteRenderer
->SendNotifyRegionInvalidated(aRegion
);
512 ClientLayerManager::StartFrameTimeRecording(int32_t aBufferSize
)
514 CompositorChild
* renderer
= GetRemoteRenderer();
517 renderer
->SendStartFrameTimeRecording(aBufferSize
, &startIndex
);
524 ClientLayerManager::StopFrameTimeRecording(uint32_t aStartIndex
,
525 nsTArray
<float>& aFrameIntervals
)
527 CompositorChild
* renderer
= GetRemoteRenderer();
529 renderer
->SendStopFrameTimeRecording(aStartIndex
, &aFrameIntervals
);
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();
547 transactionStart
= mTransactionStart
;
550 // forward this transaction's changeset to our LayerManagerComposite
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());
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());
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
) {
594 RefPtr
<TextureClient
> texture
= TextureClient::AsTextureClient(child
);
596 texture
->SetReleaseFenceHandle(fence
);
602 NS_RUNTIMEABORT("not reached");
607 mNeedsComposite
= false;
609 } else if (HasShadowManager()) {
610 NS_WARNING("failed to forward Layers transaction");
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();
624 // this may result in Layers being deleted, which results in
625 // PLayer::Send__delete__() and DeallocShmem()
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
);
643 ClientLayerManager::IsCompositingCheap()
645 // Whether compositing is cheap depends on the parent backend.
646 return mForwarder
->mShadowManager
&&
647 LayerManager::IsCompositingCheap(mForwarder
->GetCompositorBackendType());
651 ClientLayerManager::AreComponentAlphaLayersEnabled()
653 return GetCompositorBackendType() != LayersBackend::LAYERS_BASIC
&&
654 LayerManager::AreComponentAlphaLayersEnabled();
658 ClientLayerManager::SetIsFirstPaint()
660 mForwarder
->SetIsFirstPaint();
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(),
679 return mTexturePools
.LastElement();
683 ClientLayerManager::ReturnTextureClientDeferred(TextureClient
& aClient
) {
684 GetTexturePool(aClient
.GetFormat())->ReturnTextureClientDeferred(&aClient
);
688 ClientLayerManager::ReturnTextureClient(TextureClient
& aClient
) {
689 GetTexturePool(aClient
.GetFormat())->ReturnTextureClient(&aClient
);
693 ClientLayerManager::ReportClientLost(TextureClient
& aClient
) {
694 GetTexturePool(aClient
.GetFormat())->ReportClientLost();
698 ClientLayerManager::ClearCachedResources(Layer
* aSubtree
)
700 MOZ_ASSERT(!HasShadowManager() || !aSubtree
);
701 mForwarder
->ClearCachedResources();
703 ClearLayer(aSubtree
);
707 for (size_t i
= 0; i
< mTexturePools
.Length(); i
++) {
708 mTexturePools
[i
]->Clear();
713 ClientLayerManager::HandleMemoryPressure()
715 for (size_t i
= 0; i
< mTexturePools
.Length(); i
++) {
716 mTexturePools
[i
]->ShrinkToMinimumSize();
721 ClientLayerManager::ClearLayer(Layer
* aLayer
)
723 ClientLayer::ToClientLayer(aLayer
)->ClearCachedResources();
724 for (Layer
* child
= aLayer
->GetFirstChild(); child
;
725 child
= child
->GetNextSibling()) {
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");
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
,
763 aMetrics
.SetScrollOffset(scrollOffset
/ zoom
);
764 aMetrics
.SetZoom(zoom
);
771 ClientLayer::~ClientLayer()
774 PLayerChild::Send__delete__(GetShadow());
776 MOZ_COUNT_DTOR(ClientLayer
);