Bug 825928: Land layers refactoring. r=jrmuizel,bas,nical,mattwoodrow,roc,nrc,benwa,bjacob,jgilbert,kchen CLOSED TREE
Please contact Bas Schouten <bschouten@mozilla.com>, Nicolas Silva <nsilva@mozilla.com> or Nicholas Cameron <ncameron@mozilla.com> with general questions. Below is a rough list of authors to contact with specific questions. Authors: gfx/layers/Compositor.* gfx/layers/Effects.h - Compositor Interface - bas,nrc,nical gfx/layers/d3d* - D3D9/D3D10 - bas gfx/layers/ThebesLayer* - ThebesLayers - nrc,bas gfx/layers/composite/* - CompositeLayers - nrc,nical gfx/layers/client/* - Client - nrc,nical,bas gfx/layers/*Image* - nical gfx/layers/ipc ipc - IPC - nical gfx/layers/opengl - CompositorOGL - nrc,nical gfx/2d - bas,nrc gfx/gl - GLContext - bjacob dom/* layout/* - DOM - mattwoodrow
This commit is contained in:
@@ -8,6 +8,7 @@
|
||||
#include "mozilla/layers/PLayerChild.h"
|
||||
#include "mozilla/layers/PLayersChild.h"
|
||||
#include "mozilla/layers/PLayersParent.h"
|
||||
#include "mozilla/layers/TextureChild.h"
|
||||
|
||||
#include "gfxSharedImageSurface.h"
|
||||
#include "gfxImageSurface.h"
|
||||
@@ -113,11 +114,11 @@ ToInsideIntRect(const gfxRect& aRect)
|
||||
// around. It also uses ensures that the Transform and Opaque rect are restored
|
||||
// to their former state on destruction.
|
||||
|
||||
class PaintContext {
|
||||
class PaintLayerContext {
|
||||
public:
|
||||
PaintContext(gfxContext* aTarget, Layer* aLayer,
|
||||
LayerManager::DrawThebesLayerCallback aCallback,
|
||||
void* aCallbackData, ReadbackProcessor* aReadback)
|
||||
PaintLayerContext(gfxContext* aTarget, Layer* aLayer,
|
||||
LayerManager::DrawThebesLayerCallback aCallback,
|
||||
void* aCallbackData, ReadbackProcessor* aReadback)
|
||||
: mTarget(aTarget)
|
||||
, mTargetMatrixSR(aTarget)
|
||||
, mLayer(aLayer)
|
||||
@@ -127,7 +128,7 @@ public:
|
||||
, mPushedOpaqueRect(false)
|
||||
{}
|
||||
|
||||
~PaintContext()
|
||||
~PaintLayerContext()
|
||||
{
|
||||
// Matrix is restored by mTargetMatrixSR
|
||||
if (mPushedOpaqueRect)
|
||||
@@ -539,7 +540,7 @@ BasicLayerManager::EndTransactionInternal(DrawThebesLayerCallback aCallback,
|
||||
|
||||
if (aFlags & END_NO_COMPOSITE) {
|
||||
if (!mDummyTarget) {
|
||||
// TODO: We should really just set mTarget to null and make sure we can handle that further down the call chain
|
||||
// XXX: We should really just set mTarget to null and make sure we can handle that further down the call chain
|
||||
// Creating this temporary surface can be expensive on some platforms (d2d in particular), so cache it between paints.
|
||||
nsRefPtr<gfxASurface> surf = gfxPlatform::GetPlatform()->CreateOffscreenSurface(gfxIntSize(1, 1), gfxASurface::CONTENT_COLOR);
|
||||
mDummyTarget = new gfxContext(surf);
|
||||
@@ -630,7 +631,16 @@ BasicLayerManager::EndTransactionInternal(DrawThebesLayerCallback aCallback,
|
||||
void
|
||||
BasicLayerManager::FlashWidgetUpdateArea(gfxContext *aContext)
|
||||
{
|
||||
if (gfxPlatform::GetPlatform()->WidgetUpdateFlashing()) {
|
||||
static bool sWidgetFlashingEnabled;
|
||||
static bool sWidgetFlashingPrefCached = false;
|
||||
|
||||
if (!sWidgetFlashingPrefCached) {
|
||||
sWidgetFlashingPrefCached = true;
|
||||
mozilla::Preferences::AddBoolVarCache(&sWidgetFlashingEnabled,
|
||||
"nglayout.debug.widget_update_flashing");
|
||||
}
|
||||
|
||||
if (sWidgetFlashingEnabled) {
|
||||
float r = float(rand()) / RAND_MAX;
|
||||
float g = float(rand()) / RAND_MAX;
|
||||
float b = float(rand()) / RAND_MAX;
|
||||
@@ -799,7 +809,7 @@ Transform3D(gfxASurface* aSource, gfxContext* aDest,
|
||||
}
|
||||
|
||||
void
|
||||
BasicLayerManager::PaintSelfOrChildren(PaintContext& aPaintContext,
|
||||
BasicLayerManager::PaintSelfOrChildren(PaintLayerContext& aPaintContext,
|
||||
gfxContext* aGroupTarget)
|
||||
{
|
||||
BasicImplData* data = ToData(aPaintContext.mLayer);
|
||||
@@ -841,7 +851,7 @@ BasicLayerManager::PaintSelfOrChildren(PaintContext& aPaintContext,
|
||||
}
|
||||
|
||||
void
|
||||
BasicLayerManager::FlushGroup(PaintContext& aPaintContext, bool aNeedsClipToVisibleRegion)
|
||||
BasicLayerManager::FlushGroup(PaintLayerContext& aPaintContext, bool aNeedsClipToVisibleRegion)
|
||||
{
|
||||
// If we're doing our own double-buffering, we need to avoid drawing
|
||||
// the results of an incomplete transaction to the destination surface ---
|
||||
@@ -872,7 +882,7 @@ BasicLayerManager::PaintLayer(gfxContext* aTarget,
|
||||
ReadbackProcessor* aReadback)
|
||||
{
|
||||
PROFILER_LABEL("BasicLayerManager", "PaintLayer");
|
||||
PaintContext paintContext(aTarget, aLayer, aCallback, aCallbackData, aReadback);
|
||||
PaintLayerContext paintLayerContext(aTarget, aLayer, aCallback, aCallbackData, aReadback);
|
||||
|
||||
// Don't attempt to paint layers with a singular transform, cairo will
|
||||
// just throw an error.
|
||||
@@ -901,7 +911,7 @@ BasicLayerManager::PaintLayer(gfxContext* aTarget,
|
||||
gfxContextAutoSaveRestore contextSR;
|
||||
gfxMatrix transform;
|
||||
// Will return an identity matrix for 3d transforms, and is handled separately below.
|
||||
bool is2D = paintContext.Setup2DTransform();
|
||||
bool is2D = paintLayerContext.Setup2DTransform();
|
||||
NS_ABORT_IF_FALSE(is2D || needsGroup || !aLayer->GetFirstChild(), "Must PushGroup for 3d transforms!");
|
||||
|
||||
bool needsSaveRestore =
|
||||
@@ -916,7 +926,7 @@ BasicLayerManager::PaintLayer(gfxContext* aTarget,
|
||||
}
|
||||
}
|
||||
|
||||
paintContext.Apply2DTransform();
|
||||
paintLayerContext.Apply2DTransform();
|
||||
|
||||
const nsIntRegion& visibleRegion = aLayer->GetEffectiveVisibleRegion();
|
||||
// If needsGroup is true, we'll clip to the visible region after we've popped the group
|
||||
@@ -927,12 +937,12 @@ BasicLayerManager::PaintLayer(gfxContext* aTarget,
|
||||
}
|
||||
|
||||
if (is2D) {
|
||||
paintContext.AnnotateOpaqueRect();
|
||||
paintLayerContext.AnnotateOpaqueRect();
|
||||
}
|
||||
|
||||
bool clipIsEmpty = !aTarget || aTarget->GetClipExtents().IsEmpty();
|
||||
if (clipIsEmpty) {
|
||||
PaintSelfOrChildren(paintContext, aTarget);
|
||||
PaintSelfOrChildren(paintLayerContext, aTarget);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -940,11 +950,11 @@ BasicLayerManager::PaintLayer(gfxContext* aTarget,
|
||||
if (needsGroup) {
|
||||
nsRefPtr<gfxContext> groupTarget = PushGroupForLayer(aTarget, aLayer, aLayer->GetEffectiveVisibleRegion(),
|
||||
&needsClipToVisibleRegion);
|
||||
PaintSelfOrChildren(paintContext, groupTarget);
|
||||
PaintSelfOrChildren(paintLayerContext, groupTarget);
|
||||
PopGroupToSourceWithCachedSurface(aTarget, groupTarget);
|
||||
FlushGroup(paintContext, needsClipToVisibleRegion);
|
||||
FlushGroup(paintLayerContext, needsClipToVisibleRegion);
|
||||
} else {
|
||||
PaintSelfOrChildren(paintContext, aTarget);
|
||||
PaintSelfOrChildren(paintLayerContext, aTarget);
|
||||
}
|
||||
} else {
|
||||
const nsIntRect& bounds = visibleRegion.GetBounds();
|
||||
@@ -957,7 +967,7 @@ BasicLayerManager::PaintLayer(gfxContext* aTarget,
|
||||
untransformedSurface->SetDeviceOffset(gfxPoint(-bounds.x, -bounds.y));
|
||||
nsRefPtr<gfxContext> groupTarget = new gfxContext(untransformedSurface);
|
||||
|
||||
PaintSelfOrChildren(paintContext, groupTarget);
|
||||
PaintSelfOrChildren(paintLayerContext, groupTarget);
|
||||
|
||||
// Temporary fast fix for bug 725886
|
||||
// Revert these changes when 725886 is ready
|
||||
@@ -991,7 +1001,7 @@ BasicLayerManager::PaintLayer(gfxContext* aTarget,
|
||||
aTarget->NewPath();
|
||||
aTarget->Rectangle(destRect, true);
|
||||
aTarget->Clip();
|
||||
FlushGroup(paintContext, needsClipToVisibleRegion);
|
||||
FlushGroup(paintLayerContext, needsClipToVisibleRegion);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1124,12 +1134,21 @@ BasicShadowLayerManager::BeginTransactionWithTarget(gfxContext* aTarget)
|
||||
if (aTarget && (aTarget != mDefaultTarget) &&
|
||||
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),
|
||||
aTarget->OriginalSurface()->GetContentType());
|
||||
contentType);
|
||||
mDummyTarget = new gfxContext(dummy);
|
||||
aTarget = mDummyTarget;
|
||||
}
|
||||
@@ -1157,8 +1176,9 @@ BasicShadowLayerManager::EndTransaction(DrawThebesLayerCallback aCallback,
|
||||
nsIntRect bounds;
|
||||
mWidget->GetBounds(bounds);
|
||||
SurfaceDescriptor inSnapshot, snapshot;
|
||||
if (AllocBuffer(bounds.Size(), gfxASurface::CONTENT_COLOR_ALPHA,
|
||||
&inSnapshot) &&
|
||||
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|.
|
||||
@@ -1204,50 +1224,33 @@ BasicShadowLayerManager::ForwardTransaction()
|
||||
const EditReply& reply = replies[i];
|
||||
|
||||
switch (reply.type()) {
|
||||
case EditReply::TOpThebesBufferSwap: {
|
||||
MOZ_LAYERS_LOG(("[LayersForwarder] ThebesBufferSwap"));
|
||||
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());
|
||||
|
||||
const OpThebesBufferSwap& obs = reply.get_OpThebesBufferSwap();
|
||||
BasicShadowableThebesLayer* thebes = GetBasicShadowable(obs)->AsThebes();
|
||||
thebes->SetBackBufferAndAttrs(
|
||||
obs.newBackBuffer(), obs.newValidRegion(),
|
||||
obs.readOnlyFrontBuffer(), obs.frontUpdatedRegion());
|
||||
break;
|
||||
}
|
||||
case EditReply::TOpBufferSwap: {
|
||||
MOZ_LAYERS_LOG(("[LayersForwarder] BufferSwap"));
|
||||
case EditReply::TOpTextureSwap: {
|
||||
MOZ_LAYERS_LOG(("[LayersForwarder] TextureSwap"));
|
||||
|
||||
const OpBufferSwap& obs = reply.get_OpBufferSwap();
|
||||
const CanvasSurface& newBack = obs.newBackBuffer();
|
||||
if (newBack.type() == CanvasSurface::TSurfaceDescriptor) {
|
||||
GetBasicShadowable(obs)->SetBackBuffer(newBack.get_SurfaceDescriptor());
|
||||
} else if (newBack.type() == CanvasSurface::Tnull_t) {
|
||||
GetBasicShadowable(obs)->SetBackBuffer(SurfaceDescriptor());
|
||||
} else {
|
||||
NS_RUNTIMEABORT("Unknown back image type");
|
||||
}
|
||||
break;
|
||||
}
|
||||
const OpTextureSwap& ots = reply.get_OpTextureSwap();
|
||||
|
||||
case EditReply::TOpImageSwap: {
|
||||
MOZ_LAYERS_LOG(("[LayersForwarder] YUVBufferSwap"));
|
||||
PTextureChild* textureChild = ots.textureChild();
|
||||
MOZ_ASSERT(textureChild);
|
||||
|
||||
const OpImageSwap& ois = reply.get_OpImageSwap();
|
||||
BasicShadowableLayer* layer = GetBasicShadowable(ois);
|
||||
const SharedImage& newBack = ois.newBackImage();
|
||||
|
||||
if (newBack.type() == SharedImage::TSurfaceDescriptor) {
|
||||
layer->SetBackBuffer(newBack.get_SurfaceDescriptor());
|
||||
} else if (newBack.type() == SharedImage::TYUVImage) {
|
||||
const YUVImage& yuv = newBack.get_YUVImage();
|
||||
layer->SetBackBufferYUVImage(yuv.Ydata(), yuv.Udata(), yuv.Vdata());
|
||||
} else {
|
||||
layer->SetBackBuffer(SurfaceDescriptor());
|
||||
layer->SetBackBufferYUVImage(SurfaceDescriptor(),
|
||||
SurfaceDescriptor(),
|
||||
SurfaceDescriptor());
|
||||
}
|
||||
TextureClient* texClient =
|
||||
static_cast<TextureChild*>(textureChild)->GetTextureClient();
|
||||
|
||||
texClient->SetDescriptorFromReply(ots.image());
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1284,7 +1287,7 @@ BasicShadowLayerManager::IsCompositingCheap()
|
||||
{
|
||||
// Whether compositing is cheap depends on the parent backend.
|
||||
return mShadowManager &&
|
||||
LayerManager::IsCompositingCheap(GetParentBackendType());
|
||||
LayerManager::IsCompositingCheap(GetCompositorBackendType());
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1337,30 +1340,6 @@ BasicShadowLayerManager::ProgressiveUpdateCallback(bool aHasPendingNewThebesCont
|
||||
return false;
|
||||
}
|
||||
|
||||
already_AddRefed<ThebesLayer>
|
||||
BasicShadowLayerManager::CreateThebesLayer()
|
||||
{
|
||||
NS_ASSERTION(InConstruction(), "Only allowed in construction phase");
|
||||
#ifdef FORCE_BASICTILEDTHEBESLAYER
|
||||
if (HasShadowManager() && GetParentBackendType() == LAYERS_OPENGL) {
|
||||
// BasicTiledThebesLayer doesn't support main
|
||||
// thread compositing so only return this layer
|
||||
// type if we have a shadow manager.
|
||||
nsRefPtr<BasicTiledThebesLayer> layer =
|
||||
new BasicTiledThebesLayer(this);
|
||||
MAYBE_CREATE_SHADOW(Thebes);
|
||||
return layer.forget();
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
nsRefPtr<BasicShadowableThebesLayer> layer =
|
||||
new BasicShadowableThebesLayer(this);
|
||||
MAYBE_CREATE_SHADOW(Thebes);
|
||||
return layer.forget();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BasicShadowableLayer::~BasicShadowableLayer()
|
||||
{
|
||||
if (HasShadow()) {
|
||||
|
||||
Reference in New Issue
Block a user