Bug 867474 - Split BasicShadowableLayerManager into a separate ClientLayerManager. r=nrc
This commit is contained in:
@@ -20,7 +20,6 @@
|
||||
#define PIXMAN_DONT_DEFINE_STDINT
|
||||
#include "pixman.h"
|
||||
|
||||
#include "BasicTiledThebesLayer.h"
|
||||
#include "BasicLayersImpl.h"
|
||||
#include "BasicThebesLayer.h"
|
||||
#include "BasicContainerLayer.h"
|
||||
@@ -873,16 +872,6 @@ BasicLayerManager::FlushGroup(PaintLayerContext& aPaintContext, bool aNeedsClipT
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
HasOpaqueAncestorLayer(Layer* aLayer)
|
||||
{
|
||||
for (Layer* l = aLayer->GetParent(); l; l = l->GetParent()) {
|
||||
if (l->GetContentFlags() & Layer::CONTENT_OPAQUE)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
BasicLayerManager::PaintLayer(gfxContext* aTarget,
|
||||
Layer* aLayer,
|
||||
@@ -917,28 +906,6 @@ BasicLayerManager::PaintLayer(gfxContext* aTarget,
|
||||
container->UseIntermediateSurface(),
|
||||
"ContainerLayer with mask layer should force UseIntermediateSurface");
|
||||
|
||||
// If we're a shadowable ContainerLayer, then setup mSupportsComponentAlphaChildren
|
||||
// in the same way that ContainerLayerComposite will do. Otherwise leave it set to
|
||||
// true.
|
||||
ShadowableLayer* shadow = aLayer->AsShadowableLayer();
|
||||
if (aLayer->GetFirstChild() && shadow && shadow->HasShadow()) {
|
||||
if (needsGroup) {
|
||||
if (container->GetEffectiveVisibleRegion().GetNumRects() != 1 ||
|
||||
!(container->GetContentFlags() & Layer::CONTENT_OPAQUE))
|
||||
{
|
||||
const gfx3DMatrix& transform3D = container->GetEffectiveTransform();
|
||||
gfxMatrix transform;
|
||||
if (HasOpaqueAncestorLayer(container) &&
|
||||
transform3D.Is2D(&transform) && !transform.HasNonIntegerTranslation()) {
|
||||
container->SetSupportsComponentAlphaChildren(gfxPlatform::GetPlatform()->UsesSubpixelAATextRendering());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
container->SetSupportsComponentAlphaChildren((container->GetContentFlags() & Layer::CONTENT_OPAQUE) ||
|
||||
(container->GetParent() && container->GetParent()->SupportsComponentAlphaChildren()));
|
||||
}
|
||||
}
|
||||
|
||||
gfxContextAutoSaveRestore contextSR;
|
||||
gfxMatrix transform;
|
||||
// Will return an identity matrix for 3d transforms, and is handled separately below.
|
||||
@@ -1066,330 +1033,5 @@ BasicLayerManager::CreateReadbackLayer()
|
||||
return layer.forget();
|
||||
}
|
||||
|
||||
BasicShadowLayerManager::BasicShadowLayerManager(nsIWidget* aWidget) :
|
||||
BasicLayerManager(aWidget), mTargetRotation(ROTATION_0),
|
||||
mRepeatTransaction(false), mIsRepeatTransaction(false)
|
||||
{
|
||||
MOZ_COUNT_CTOR(BasicShadowLayerManager);
|
||||
}
|
||||
|
||||
BasicShadowLayerManager::~BasicShadowLayerManager()
|
||||
{
|
||||
MOZ_COUNT_DTOR(BasicShadowLayerManager);
|
||||
}
|
||||
|
||||
int32_t
|
||||
BasicShadowLayerManager::GetMaxTextureSize() const
|
||||
{
|
||||
if (HasShadowManager()) {
|
||||
return ShadowLayerForwarder::GetMaxTextureSize();
|
||||
}
|
||||
|
||||
return INT32_MAX;
|
||||
}
|
||||
|
||||
void
|
||||
BasicShadowLayerManager::SetDefaultTargetConfiguration(BufferMode aDoubleBuffering, ScreenRotation aRotation)
|
||||
{
|
||||
BasicLayerManager::SetDefaultTargetConfiguration(aDoubleBuffering, aRotation);
|
||||
mTargetRotation = aRotation;
|
||||
if (mWidget) {
|
||||
mTargetBounds = mWidget->GetNaturalBounds();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
BasicShadowLayerManager::SetRoot(Layer* aLayer)
|
||||
{
|
||||
if (mRoot != aLayer) {
|
||||
if (HasShadowManager()) {
|
||||
// Have to hold the old root and its children in order to
|
||||
// maintain the same view of the layer tree in this process as
|
||||
// the parent sees. Otherwise layers can be destroyed
|
||||
// mid-transaction and bad things can happen (v. bug 612573)
|
||||
if (mRoot) {
|
||||
Hold(mRoot);
|
||||
}
|
||||
ShadowLayerForwarder::SetRoot(Hold(aLayer));
|
||||
}
|
||||
BasicLayerManager::SetRoot(aLayer);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
BasicShadowLayerManager::Mutated(Layer* aLayer)
|
||||
{
|
||||
BasicLayerManager::Mutated(aLayer);
|
||||
|
||||
NS_ASSERTION(InConstruction() || InDrawing(), "wrong phase");
|
||||
if (HasShadowManager() && ShouldShadow(aLayer)) {
|
||||
ShadowLayerForwarder::Mutated(Hold(aLayer));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
BasicShadowLayerManager::BeginTransactionWithTarget(gfxContext* aTarget)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(mKeepAlive.IsEmpty(), "uncommitted txn?");
|
||||
nsRefPtr<gfxContext> targetContext = aTarget;
|
||||
|
||||
// If the last transaction was incomplete (a failed DoEmptyTransaction),
|
||||
// don't signal a new transaction to ShadowLayerForwarder. Carry on adding
|
||||
// to the previous transaction.
|
||||
if (HasShadowManager()) {
|
||||
ScreenOrientation orientation;
|
||||
nsIntRect clientBounds;
|
||||
if (TabChild* window = mWidget->GetOwningTabChild()) {
|
||||
orientation = window->GetOrientation();
|
||||
} else {
|
||||
hal::ScreenConfiguration currentConfig;
|
||||
hal::GetCurrentScreenConfiguration(¤tConfig);
|
||||
orientation = currentConfig.orientation();
|
||||
}
|
||||
mWidget->GetClientBounds(clientBounds);
|
||||
ShadowLayerForwarder::BeginTransaction(mTargetBounds, mTargetRotation, clientBounds, orientation);
|
||||
|
||||
// If we're drawing on behalf of a context with async pan/zoom
|
||||
// enabled, then the entire buffer of thebes layers might be
|
||||
// composited (including resampling) asynchronously before we get
|
||||
// a chance to repaint, so we have to ensure that it's all valid
|
||||
// and not rotated.
|
||||
if (mWidget) {
|
||||
if (TabChild* window = mWidget->GetOwningTabChild()) {
|
||||
mCompositorMightResample = window->IsAsyncPanZoomEnabled();
|
||||
}
|
||||
}
|
||||
|
||||
// If we have a non-default target, we need to let our shadow manager draw
|
||||
// to it. This will happen at the end of the transaction.
|
||||
if (aTarget && ((aTarget != mDefaultTarget) || Compositor::GetBackend() == LAYERS_BASIC) &&
|
||||
XRE_GetProcessType() == GeckoProcessType_Default) {
|
||||
mShadowTarget = aTarget;
|
||||
|
||||
gfxASurface::gfxContentType contentType;
|
||||
|
||||
if (aTarget->IsCairo()) {
|
||||
contentType = aTarget->OriginalSurface()->GetContentType();
|
||||
} else {
|
||||
contentType = aTarget->GetDrawTarget()->GetFormat() == FORMAT_B8G8R8X8 ?
|
||||
gfxASurface::CONTENT_COLOR : gfxASurface::CONTENT_COLOR_ALPHA;
|
||||
}
|
||||
// Create a temporary target for ourselves, so that
|
||||
// mShadowTarget is only drawn to for the window snapshot.
|
||||
nsRefPtr<gfxASurface> dummy =
|
||||
gfxPlatform::GetPlatform()->CreateOffscreenSurface(
|
||||
gfxIntSize(1, 1),
|
||||
contentType);
|
||||
mDummyTarget = new gfxContext(dummy);
|
||||
aTarget = mDummyTarget;
|
||||
}
|
||||
}
|
||||
BasicLayerManager::BeginTransactionWithTarget(aTarget);
|
||||
}
|
||||
|
||||
void
|
||||
BasicShadowLayerManager::EndTransaction(DrawThebesLayerCallback aCallback,
|
||||
void* aCallbackData,
|
||||
EndTransactionFlags aFlags)
|
||||
{
|
||||
if (mWidget) {
|
||||
mWidget->PrepareWindowEffects();
|
||||
}
|
||||
BasicLayerManager::EndTransaction(aCallback, aCallbackData, aFlags);
|
||||
ForwardTransaction();
|
||||
|
||||
if (mRepeatTransaction) {
|
||||
mRepeatTransaction = false;
|
||||
mIsRepeatTransaction = true;
|
||||
BasicLayerManager::BeginTransaction();
|
||||
BasicShadowLayerManager::EndTransaction(aCallback, aCallbackData, aFlags);
|
||||
mIsRepeatTransaction = false;
|
||||
} else {
|
||||
MakeSnapshotIfRequired();
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
BasicShadowLayerManager::EndEmptyTransaction(EndTransactionFlags aFlags)
|
||||
{
|
||||
if (!BasicLayerManager::EndEmptyTransaction(aFlags)) {
|
||||
// Return without calling ForwardTransaction. This leaves the
|
||||
// ShadowLayerForwarder transaction open; the following
|
||||
// EndTransaction will complete it.
|
||||
return false;
|
||||
}
|
||||
ForwardTransaction();
|
||||
MakeSnapshotIfRequired();
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
BasicShadowLayerManager::MakeSnapshotIfRequired()
|
||||
{
|
||||
if (!mShadowTarget) {
|
||||
return;
|
||||
}
|
||||
if (mWidget) {
|
||||
if (CompositorChild* remoteRenderer = mWidget->GetRemoteRenderer()) {
|
||||
nsIntRect bounds;
|
||||
mWidget->GetBounds(bounds);
|
||||
SurfaceDescriptor inSnapshot, snapshot;
|
||||
if (AllocSurfaceDescriptor(bounds.Size(),
|
||||
gfxASurface::CONTENT_COLOR_ALPHA,
|
||||
&inSnapshot) &&
|
||||
// The compositor will usually reuse |snapshot| and return
|
||||
// it through |outSnapshot|, but if it doesn't, it's
|
||||
// responsible for freeing |snapshot|.
|
||||
remoteRenderer->SendMakeSnapshot(inSnapshot, &snapshot)) {
|
||||
AutoOpenSurface opener(OPEN_READ_ONLY, snapshot);
|
||||
gfxASurface* source = opener.Get();
|
||||
|
||||
mShadowTarget->DrawSurface(source, source->GetSize());
|
||||
}
|
||||
if (IsSurfaceDescriptorValid(snapshot)) {
|
||||
ShadowLayerForwarder::DestroySharedSurface(&snapshot);
|
||||
}
|
||||
}
|
||||
}
|
||||
mShadowTarget = nullptr;
|
||||
mDummyTarget = nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
BasicShadowLayerManager::ForwardTransaction()
|
||||
{
|
||||
RenderTraceScope rendertrace("Foward Transaction", "000090");
|
||||
mPhase = PHASE_FORWARD;
|
||||
|
||||
// forward this transaction's changeset to our LayerManagerComposite
|
||||
AutoInfallibleTArray<EditReply, 10> replies;
|
||||
if (HasShadowManager() && ShadowLayerForwarder::EndTransaction(&replies)) {
|
||||
for (nsTArray<EditReply>::size_type i = 0; i < replies.Length(); ++i) {
|
||||
const EditReply& reply = replies[i];
|
||||
|
||||
switch (reply.type()) {
|
||||
case EditReply::TOpContentBufferSwap: {
|
||||
MOZ_LAYERS_LOG(("[LayersForwarder] DoubleBufferSwap"));
|
||||
|
||||
const OpContentBufferSwap& obs = reply.get_OpContentBufferSwap();
|
||||
|
||||
CompositableChild* compositableChild =
|
||||
static_cast<CompositableChild*>(obs.compositableChild());
|
||||
ContentClientRemote* contentClient =
|
||||
static_cast<ContentClientRemote*>(compositableChild->GetCompositableClient());
|
||||
MOZ_ASSERT(contentClient);
|
||||
|
||||
contentClient->SwapBuffers(obs.frontUpdatedRegion());
|
||||
|
||||
break;
|
||||
}
|
||||
case EditReply::TOpTextureSwap: {
|
||||
MOZ_LAYERS_LOG(("[LayersForwarder] TextureSwap"));
|
||||
|
||||
const OpTextureSwap& ots = reply.get_OpTextureSwap();
|
||||
|
||||
CompositableChild* compositableChild =
|
||||
static_cast<CompositableChild*>(ots.compositableChild());
|
||||
MOZ_ASSERT(compositableChild);
|
||||
|
||||
compositableChild->GetCompositableClient()
|
||||
->SetDescriptorFromReply(ots.textureId(), ots.image());
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
NS_RUNTIMEABORT("not reached");
|
||||
}
|
||||
}
|
||||
} else if (HasShadowManager()) {
|
||||
NS_WARNING("failed to forward Layers transaction");
|
||||
}
|
||||
|
||||
mPhase = PHASE_NONE;
|
||||
|
||||
// this may result in Layers being deleted, which results in
|
||||
// PLayer::Send__delete__() and DeallocShmem()
|
||||
mKeepAlive.Clear();
|
||||
}
|
||||
|
||||
ShadowableLayer*
|
||||
BasicShadowLayerManager::Hold(Layer* aLayer)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(HasShadowManager(),
|
||||
"top-level tree, no shadow tree to remote to");
|
||||
|
||||
ShadowableLayer* shadowable = ToShadowable(aLayer);
|
||||
NS_ABORT_IF_FALSE(shadowable, "trying to remote an unshadowable layer");
|
||||
|
||||
mKeepAlive.AppendElement(aLayer);
|
||||
return shadowable;
|
||||
}
|
||||
|
||||
bool
|
||||
BasicShadowLayerManager::IsCompositingCheap()
|
||||
{
|
||||
// Whether compositing is cheap depends on the parent backend.
|
||||
return mShadowManager &&
|
||||
LayerManager::IsCompositingCheap(GetCompositorBackendType());
|
||||
}
|
||||
|
||||
void
|
||||
BasicShadowLayerManager::SetIsFirstPaint()
|
||||
{
|
||||
ShadowLayerForwarder::SetIsFirstPaint();
|
||||
}
|
||||
|
||||
void
|
||||
BasicShadowLayerManager::ClearCachedResources(Layer* aSubtree)
|
||||
{
|
||||
MOZ_ASSERT(!HasShadowManager() || !aSubtree);
|
||||
if (PLayerTransactionChild* manager = GetShadowManager()) {
|
||||
manager->SendClearCachedResources();
|
||||
}
|
||||
BasicLayerManager::ClearCachedResources(aSubtree);
|
||||
}
|
||||
|
||||
bool
|
||||
BasicShadowLayerManager::ProgressiveUpdateCallback(bool aHasPendingNewThebesContent,
|
||||
gfx::Rect& aViewport,
|
||||
float& aScaleX,
|
||||
float& aScaleY,
|
||||
bool aDrawingCritical)
|
||||
{
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
Layer* primaryScrollable = GetPrimaryScrollableLayer();
|
||||
if (primaryScrollable) {
|
||||
const FrameMetrics& metrics = primaryScrollable->AsContainerLayer()->GetFrameMetrics();
|
||||
|
||||
// This is derived from the code in
|
||||
// gfx/layers/ipc/CompositorParent.cpp::TransformShadowTree.
|
||||
const gfx3DMatrix& rootTransform = GetRoot()->GetTransform();
|
||||
float devPixelRatioX = 1 / rootTransform.GetXScale();
|
||||
float devPixelRatioY = 1 / rootTransform.GetYScale();
|
||||
const gfx::Rect& metricsDisplayPort =
|
||||
(aDrawingCritical && !metrics.mCriticalDisplayPort.IsEmpty()) ?
|
||||
metrics.mCriticalDisplayPort : metrics.mDisplayPort;
|
||||
gfx::Rect displayPort((metricsDisplayPort.x + metrics.mScrollOffset.x) * devPixelRatioX,
|
||||
(metricsDisplayPort.y + metrics.mScrollOffset.y) * devPixelRatioY,
|
||||
metricsDisplayPort.width * devPixelRatioX,
|
||||
metricsDisplayPort.height * devPixelRatioY);
|
||||
|
||||
return AndroidBridge::Bridge()->ProgressiveUpdateCallback(
|
||||
aHasPendingNewThebesContent, displayPort, devPixelRatioX, aDrawingCritical,
|
||||
aViewport, aScaleX, aScaleY);
|
||||
}
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
BasicShadowableLayer::~BasicShadowableLayer()
|
||||
{
|
||||
if (HasShadow()) {
|
||||
PLayerChild::Send__delete__(GetShadow());
|
||||
}
|
||||
MOZ_COUNT_DTOR(BasicShadowableLayer);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user