зеркало из https://github.com/mozilla/gecko-dev.git
Bug 922942 - Add a Validate() pass to BasicLayers to avoid needing to create a dummy destination context. r=roc
This commit is contained in:
Родитель
762844a6e0
Коммит
c8d82e8dcd
|
@ -115,6 +115,20 @@ BasicContainerLayer::ChildrenPartitionVisibleRegion(const nsIntRect& aInRect)
|
|||
return covered.Contains(rect);
|
||||
}
|
||||
|
||||
void
|
||||
BasicContainerLayer::Validate(LayerManager::DrawThebesLayerCallback aCallback,
|
||||
void* aCallbackData)
|
||||
{
|
||||
for (Layer* l = mFirstChild; l; l = l->GetNextSibling()) {
|
||||
BasicImplData* data = ToData(l);
|
||||
data->Validate(aCallback, aCallbackData);
|
||||
if (l->GetMaskLayer()) {
|
||||
data = ToData(l->GetMaskLayer());
|
||||
data->Validate(aCallback, aCallbackData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
already_AddRefed<ContainerLayer>
|
||||
BasicLayerManager::CreateContainerLayer()
|
||||
{
|
||||
|
|
|
@ -76,6 +76,9 @@ public:
|
|||
|
||||
void SetSupportsComponentAlphaChildren(bool aSupports) { mSupportsComponentAlphaChildren = aSupports; }
|
||||
|
||||
virtual void Validate(LayerManager::DrawThebesLayerCallback aCallback,
|
||||
void* aCallbackData) MOZ_OVERRIDE;
|
||||
|
||||
protected:
|
||||
BasicLayerManager* BasicManager()
|
||||
{
|
||||
|
|
|
@ -73,6 +73,9 @@ public:
|
|||
void* aCallbackData,
|
||||
ReadbackProcessor* aReadback) {}
|
||||
|
||||
virtual void Validate(LayerManager::DrawThebesLayerCallback aCallback,
|
||||
void* aCallbackData) {}
|
||||
|
||||
/**
|
||||
* Layers will get this call when their layer manager is destroyed, this
|
||||
* indicates they should clear resources they don't really need after their
|
||||
|
|
|
@ -581,22 +581,32 @@ BasicLayerManager::EndTransactionInternal(DrawThebesLayerCallback aCallback,
|
|||
NS_ASSERTION(InConstruction(), "Should be in construction phase");
|
||||
mPhase = PHASE_DRAWING;
|
||||
|
||||
Layer* aLayer = GetRoot();
|
||||
RenderTraceLayers(aLayer, "FF00");
|
||||
RenderTraceLayers(mRoot, "FF00");
|
||||
|
||||
mTransactionIncomplete = false;
|
||||
|
||||
if (aFlags & END_NO_COMPOSITE) {
|
||||
if (!mDummyTarget) {
|
||||
// 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), GFX_CONTENT_COLOR);
|
||||
mDummyTarget = new gfxContext(surf);
|
||||
if (mRoot) {
|
||||
// Need to do this before we call ApplyDoubleBuffering,
|
||||
// which depends on correct effective transforms
|
||||
mSnapEffectiveTransforms =
|
||||
mTarget ? !(mTarget->GetFlags() & gfxContext::FLAG_DISABLE_SNAPPING) : true;
|
||||
mRoot->ComputeEffectiveTransforms(mTarget ? gfx3DMatrix::From2D(mTarget->CurrentMatrix()) : gfx3DMatrix());
|
||||
|
||||
ToData(mRoot)->Validate(aCallback, aCallbackData);
|
||||
if (mRoot->GetMaskLayer()) {
|
||||
ToData(mRoot->GetMaskLayer())->Validate(aCallback, aCallbackData);
|
||||
}
|
||||
|
||||
if (aFlags & END_NO_COMPOSITE) {
|
||||
// Apply pending tree updates before recomputing effective
|
||||
// properties.
|
||||
mRoot->ApplyPendingUpdatesToSubtree();
|
||||
}
|
||||
mTarget = mDummyTarget;
|
||||
}
|
||||
|
||||
if (mTarget && mRoot && !(aFlags & END_NO_IMMEDIATE_REDRAW)) {
|
||||
if (mTarget && mRoot &&
|
||||
!(aFlags & END_NO_IMMEDIATE_REDRAW) &&
|
||||
!(aFlags & END_NO_COMPOSITE)) {
|
||||
nsIntRect clipRect;
|
||||
|
||||
{
|
||||
|
@ -605,18 +615,6 @@ BasicLayerManager::EndTransactionInternal(DrawThebesLayerCallback aCallback,
|
|||
clipRect = ToOutsideIntRect(mTarget->GetClipExtents());
|
||||
}
|
||||
|
||||
if (aFlags & END_NO_COMPOSITE) {
|
||||
// Apply pending tree updates before recomputing effective
|
||||
// properties.
|
||||
aLayer->ApplyPendingUpdatesToSubtree();
|
||||
}
|
||||
|
||||
// Need to do this before we call ApplyDoubleBuffering,
|
||||
// which depends on correct effective transforms
|
||||
mSnapEffectiveTransforms =
|
||||
!(mTarget->GetFlags() & gfxContext::FLAG_DISABLE_SNAPPING);
|
||||
mRoot->ComputeEffectiveTransforms(gfx3DMatrix::From2D(mTarget->CurrentMatrix()));
|
||||
|
||||
if (IsRetained()) {
|
||||
nsIntRegion region;
|
||||
MarkLayersHidden(mRoot, clipRect, clipRect, region, ALLOW_OPAQUE);
|
||||
|
@ -625,22 +623,12 @@ BasicLayerManager::EndTransactionInternal(DrawThebesLayerCallback aCallback,
|
|||
}
|
||||
}
|
||||
|
||||
if (aFlags & END_NO_COMPOSITE) {
|
||||
if (IsRetained()) {
|
||||
// Clip the destination out so that we don't draw to it, and
|
||||
// only end up validating ThebesLayers.
|
||||
mTarget->Clip(gfxRect(0, 0, 0, 0));
|
||||
PaintLayer(mTarget, mRoot, aCallback, aCallbackData, nullptr);
|
||||
}
|
||||
// If we're not retained, then don't composite means do nothing at all.
|
||||
} else {
|
||||
PaintLayer(mTarget, mRoot, aCallback, aCallbackData, nullptr);
|
||||
if (mWidget) {
|
||||
FlashWidgetUpdateArea(mTarget);
|
||||
}
|
||||
RenderDebugOverlay();
|
||||
LayerManager::PostPresent();
|
||||
PaintLayer(mTarget, mRoot, aCallback, aCallbackData, nullptr);
|
||||
if (mWidget) {
|
||||
FlashWidgetUpdateArea(mTarget);
|
||||
}
|
||||
RenderDebugOverlay();
|
||||
LayerManager::PostPresent();
|
||||
|
||||
if (!mTransactionIncomplete) {
|
||||
// Clear out target if we have a complete transaction.
|
||||
|
|
|
@ -186,7 +186,6 @@ protected:
|
|||
nsRefPtr<gfxContext> mDefaultTarget;
|
||||
// The context to draw into.
|
||||
nsRefPtr<gfxContext> mTarget;
|
||||
nsRefPtr<gfxContext> mDummyTarget;
|
||||
// Image factory we use.
|
||||
nsRefPtr<ImageFactory> mFactory;
|
||||
|
||||
|
|
|
@ -90,21 +90,11 @@ BasicThebesLayer::PaintThebes(gfxContext* aContext,
|
|||
NS_ASSERTION(BasicManager()->InDrawing(),
|
||||
"Can only draw in drawing phase");
|
||||
|
||||
if (!mContentClient) {
|
||||
// we pass a null pointer for the Forwarder argument, which means
|
||||
// this will not have a ContentHost on the other side.
|
||||
mContentClient = new ContentClientBasic(nullptr, BasicManager());
|
||||
}
|
||||
|
||||
nsTArray<ReadbackProcessor::Update> readbackUpdates;
|
||||
if (aReadback && UsedForReadback()) {
|
||||
aReadback->GetThebesLayerUpdates(this, &readbackUpdates);
|
||||
}
|
||||
|
||||
bool canUseOpaqueSurface = CanUseOpaqueSurface();
|
||||
ContentType contentType =
|
||||
canUseOpaqueSurface ? GFX_CONTENT_COLOR :
|
||||
GFX_CONTENT_COLOR_ALPHA;
|
||||
float opacity = GetEffectiveOpacity();
|
||||
gfxContext::GraphicsOperator mixBlendMode = GetEffectiveMixBlendMode();
|
||||
|
||||
|
@ -158,54 +148,6 @@ BasicThebesLayer::PaintThebes(gfxContext* aContext,
|
|||
return;
|
||||
}
|
||||
|
||||
{
|
||||
uint32_t flags = 0;
|
||||
#ifndef MOZ_WIDGET_ANDROID
|
||||
if (BasicManager()->CompositorMightResample()) {
|
||||
flags |= ThebesLayerBuffer::PAINT_WILL_RESAMPLE;
|
||||
}
|
||||
if (!(flags & ThebesLayerBuffer::PAINT_WILL_RESAMPLE)) {
|
||||
if (MayResample()) {
|
||||
flags |= ThebesLayerBuffer::PAINT_WILL_RESAMPLE;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (mDrawAtomically) {
|
||||
flags |= ThebesLayerBuffer::PAINT_NO_ROTATION;
|
||||
}
|
||||
PaintState state =
|
||||
mContentClient->BeginPaintBuffer(this, contentType, flags);
|
||||
mValidRegion.Sub(mValidRegion, state.mRegionToInvalidate);
|
||||
|
||||
if (state.mContext) {
|
||||
// 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());
|
||||
nsIntRegion extendedDrawRegion = state.mRegionToDraw;
|
||||
SetAntialiasingFlags(this, state.mContext);
|
||||
|
||||
RenderTraceInvalidateStart(this, "FFFF00", state.mRegionToDraw.GetBounds());
|
||||
|
||||
PaintBuffer(state.mContext,
|
||||
state.mRegionToDraw, extendedDrawRegion, state.mRegionToInvalidate,
|
||||
state.mDidSelfCopy,
|
||||
aCallback, aCallbackData);
|
||||
MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) PaintThebes", this));
|
||||
Mutated();
|
||||
|
||||
RenderTraceInvalidateEnd(this, "FFFF00");
|
||||
} else {
|
||||
// It's possible that state.mRegionToInvalidate is nonempty here,
|
||||
// if we are shrinking the valid region to nothing. So use mRegionToDraw
|
||||
// instead.
|
||||
NS_WARN_IF_FALSE(state.mRegionToDraw.IsEmpty(),
|
||||
"No context when we have something to draw, resource exhaustion?");
|
||||
}
|
||||
}
|
||||
|
||||
if (BasicManager()->IsTransactionIncomplete())
|
||||
return;
|
||||
|
||||
|
@ -242,6 +184,72 @@ BasicThebesLayer::PaintThebes(gfxContext* aContext,
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
BasicThebesLayer::Validate(LayerManager::DrawThebesLayerCallback aCallback,
|
||||
void* aCallbackData)
|
||||
{
|
||||
if (!mContentClient) {
|
||||
// we pass a null pointer for the Forwarder argument, which means
|
||||
// this will not have a ContentHost on the other side.
|
||||
mContentClient = new ContentClientBasic(nullptr, BasicManager());
|
||||
}
|
||||
|
||||
if (!BasicManager()->IsRetained()) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool canUseOpaqueSurface = CanUseOpaqueSurface();
|
||||
ContentType contentType =
|
||||
canUseOpaqueSurface ? GFX_CONTENT_COLOR :
|
||||
GFX_CONTENT_COLOR_ALPHA;
|
||||
|
||||
uint32_t flags = 0;
|
||||
#ifndef MOZ_WIDGET_ANDROID
|
||||
if (BasicManager()->CompositorMightResample()) {
|
||||
flags |= ThebesLayerBuffer::PAINT_WILL_RESAMPLE;
|
||||
}
|
||||
if (!(flags & ThebesLayerBuffer::PAINT_WILL_RESAMPLE)) {
|
||||
if (MayResample()) {
|
||||
flags |= ThebesLayerBuffer::PAINT_WILL_RESAMPLE;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (mDrawAtomically) {
|
||||
flags |= ThebesLayerBuffer::PAINT_NO_ROTATION;
|
||||
}
|
||||
PaintState state =
|
||||
mContentClient->BeginPaintBuffer(this, contentType, flags);
|
||||
mValidRegion.Sub(mValidRegion, state.mRegionToInvalidate);
|
||||
|
||||
if (state.mContext) {
|
||||
// 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());
|
||||
nsIntRegion extendedDrawRegion = state.mRegionToDraw;
|
||||
SetAntialiasingFlags(this, state.mContext);
|
||||
|
||||
RenderTraceInvalidateStart(this, "FFFF00", state.mRegionToDraw.GetBounds());
|
||||
|
||||
PaintBuffer(state.mContext,
|
||||
state.mRegionToDraw, extendedDrawRegion, state.mRegionToInvalidate,
|
||||
state.mDidSelfCopy,
|
||||
aCallback, aCallbackData);
|
||||
MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) PaintThebes", this));
|
||||
Mutated();
|
||||
|
||||
RenderTraceInvalidateEnd(this, "FFFF00");
|
||||
} else {
|
||||
// It's possible that state.mRegionToInvalidate is nonempty here,
|
||||
// if we are shrinking the valid region to nothing. So use mRegionToDraw
|
||||
// instead.
|
||||
NS_WARN_IF_FALSE(state.mRegionToDraw.IsEmpty(),
|
||||
"No context when we have something to draw, resource exhaustion?");
|
||||
}
|
||||
}
|
||||
|
||||
already_AddRefed<ThebesLayer>
|
||||
BasicLayerManager::CreateThebesLayer()
|
||||
{
|
||||
|
|
|
@ -64,6 +64,9 @@ public:
|
|||
void* aCallbackData,
|
||||
ReadbackProcessor* aReadback);
|
||||
|
||||
virtual void Validate(LayerManager::DrawThebesLayerCallback aCallback,
|
||||
void* aCallbackData) MOZ_OVERRIDE;
|
||||
|
||||
virtual void ClearCachedResources()
|
||||
{
|
||||
if (mContentClient) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче