Bug 1727423 - Remove BasicLayerManager. r=jrmuizel

Differential Revision: https://phabricator.services.mozilla.com/D123555
This commit is contained in:
Matt Woodrow 2021-08-25 07:35:17 +00:00
Родитель 15827952f9
Коммит 7755c29fd8
33 изменённых файлов: 13 добавлений и 2531 удалений

Просмотреть файл

@ -56,7 +56,6 @@ class DrawTarget;
namespace layers {
class AsyncPanZoomController;
class BasicLayerManager;
class ClientLayerManager;
class HostLayerManager;
class Layer;
@ -165,7 +164,6 @@ class LayerManager : public WindowRenderer {
virtual LayerManagerComposite* AsLayerManagerComposite() { return nullptr; }
virtual BasicLayerManager* AsBasicLayerManager() { return nullptr; }
virtual HostLayerManager* AsHostLayerManager() { return nullptr; }
virtual WebRenderLayerManager* AsWebRenderLayerManager() { return nullptr; }

Просмотреть файл

@ -11,9 +11,7 @@
#include <algorithm> // for max
#include <utility> // for Move
#include "BasicImplData.h" // for BasicImplData
#include "BasicLayersImpl.h" // for ToData
#include "Layers.h" // for PaintedLayer, Layer, etc
#include "Layers.h" // for PaintedLayer, Layer, etc
#include "gfx2DGlue.h"
#include "gfxPlatform.h" // for gfxPlatform
#include "gfxUtils.h" // for gfxUtils
@ -203,36 +201,6 @@ static bool IsClippingCheap(gfx::DrawTarget* aTarget,
aRegion.GetNumRects() <= 1;
}
void RotatedBuffer::DrawTo(PaintedLayer* aLayer, DrawTarget* aTarget,
float aOpacity, CompositionOp aOp,
SourceSurface* aMask, const Matrix* aMaskTransform) {
bool clipped = false;
// If the entire buffer is valid, we can just draw the whole thing,
// no need to clip. But we'll still clip if clipping is cheap ---
// that might let us copy a smaller region of the buffer.
// Also clip to the visible region if we're told to.
if (!aLayer->GetValidRegion().Contains(BufferRect()) ||
(ToData(aLayer)->GetClipToVisibleRegion() &&
!aLayer->GetVisibleRegion().ToUnknownRegion().Contains(BufferRect())) ||
IsClippingCheap(aTarget,
aLayer->GetLocalVisibleRegion().ToUnknownRegion())) {
// We don't want to draw invalid stuff, so we need to clip. Might as
// well clip to the smallest area possible --- the visible region.
// Bug 599189 if there is a non-integer-translation transform in aTarget,
// we might sample pixels outside GetLocalVisibleRegion(), which is wrong
// and may cause gray lines.
gfxUtils::ClipToRegion(aTarget,
aLayer->GetLocalVisibleRegion().ToUnknownRegion());
clipped = true;
}
DrawBufferWithRotation(aTarget, aOpacity, aOp, aMask, aMaskTransform);
if (clipped) {
aTarget->PopClip();
}
}
void RotatedBuffer::UpdateDestinationFrom(const RotatedBuffer& aSource,
const gfx::IntRect& aUpdateRect) {
DrawIterator iter;

Просмотреть файл

@ -98,15 +98,6 @@ class RotatedBuffer : public BorrowDrawTarget {
gfx::SourceSurface* aMask = nullptr,
const gfx::Matrix* aMaskTransform = nullptr) const;
/**
* Complete the drawing operation. The region to draw must have been
* drawn before this is called. The contents of the buffer are drawn
* to aTarget.
*/
void DrawTo(PaintedLayer* aLayer, gfx::DrawTarget* aTarget, float aOpacity,
gfx::CompositionOp aOp, gfx::SourceSurface* aMask,
const gfx::Matrix* aMaskTransform);
/**
* Update the specified region of this rotated buffer with the contents
* of a source rotated buffer.

Просмотреть файл

@ -1,77 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "BasicCanvasLayer.h"
#include "basic/BasicLayers.h" // for BasicLayerManager
#include "basic/BasicLayersImpl.h" // for GetEffectiveOperator
#include "CanvasRenderer.h"
#include "mozilla/mozalloc.h" // for operator new
#include "mozilla/Maybe.h"
#include "nsCOMPtr.h" // for already_AddRefed
#include "nsISupportsImpl.h" // for Layer::AddRef, etc
#include "gfx2DGlue.h"
#include "GLScreenBuffer.h"
#include "GLContext.h"
#include "gfxUtils.h"
#include "mozilla/layers/PersistentBufferProvider.h"
#include "client/TextureClientSharedSurface.h"
class gfxContext;
using namespace mozilla::gfx;
using namespace mozilla::gl;
namespace mozilla {
namespace layers {
void BasicCanvasLayer::Paint(DrawTarget* aDT, const Point& aDeviceOffset,
Layer* aMaskLayer) {
if (IsHidden()) return;
// Ignore IsDirty().
MOZ_ASSERT(mCanvasRenderer);
mCanvasRenderer->FirePreTransactionCallback();
const auto snapshot = mCanvasRenderer->BorrowSnapshot();
if (!snapshot) return;
const auto& surface = snapshot->mSurf;
Maybe<Matrix> oldTM;
if (!mCanvasRenderer->YIsDown()) {
// y-flip
oldTM = Some(aDT->GetTransform());
aDT->SetTransform(Matrix(*oldTM)
.PreTranslate(0.0f, mBounds.Height())
.PreScale(1.0f, -1.0f));
}
FillRectWithMask(
aDT, aDeviceOffset, Rect(0, 0, mBounds.Width(), mBounds.Height()),
surface, mSamplingFilter,
DrawOptions(GetEffectiveOpacity(), GetEffectiveOperator(this)),
aMaskLayer);
if (oldTM) {
aDT->SetTransform(*oldTM);
}
mCanvasRenderer->FireDidTransactionCallback();
Painted();
}
RefPtr<CanvasRenderer> BasicCanvasLayer::CreateCanvasRendererInternal() {
return new CanvasRenderer();
}
already_AddRefed<CanvasLayer> BasicLayerManager::CreateCanvasLayer() {
NS_ASSERTION(InConstruction(), "Only allowed in construction phase");
RefPtr<CanvasLayer> layer = new BasicCanvasLayer(this);
return layer.forget();
}
} // namespace layers
} // namespace mozilla

Просмотреть файл

@ -1,44 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef GFX_BASICCANVASLAYER_H
#define GFX_BASICCANVASLAYER_H
#include "BasicImplData.h" // for BasicImplData
#include "BasicLayers.h" // for BasicLayerManager
#include "Layers.h" // for CanvasLayer, etc
#include "nsDebug.h" // for NS_ASSERTION
#include "nsRegion.h" // for nsIntRegion
namespace mozilla {
namespace layers {
class BasicCanvasLayer : public CanvasLayer, public BasicImplData {
public:
explicit BasicCanvasLayer(BasicLayerManager* aLayerManager)
: CanvasLayer(aLayerManager, static_cast<BasicImplData*>(this)) {}
void SetVisibleRegion(const LayerIntRegion& aRegion) override {
NS_ASSERTION(BasicManager()->InConstruction(),
"Can only set properties in construction phase");
CanvasLayer::SetVisibleRegion(aRegion);
}
void Paint(gfx::DrawTarget* aDT, const gfx::Point& aDeviceOffset,
Layer* aMaskLayer) override;
protected:
BasicLayerManager* BasicManager() {
return static_cast<BasicLayerManager*>(mManager);
}
RefPtr<CanvasRenderer> CreateCanvasRendererInternal() override;
};
} // namespace layers
} // namespace mozilla
#endif

Просмотреть файл

@ -1,75 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "BasicLayersImpl.h" // for FillRectWithMask, etc
#include "Layers.h" // for ColorLayer, etc
#include "BasicImplData.h" // for BasicImplData
#include "BasicLayers.h" // for BasicLayerManager
#include "gfxContext.h" // for gfxContext, etc
#include "gfxRect.h" // for gfxRect
#include "gfx2DGlue.h"
#include "mozilla/mozalloc.h" // for operator new
#include "nsCOMPtr.h" // for already_AddRefed
#include "nsDebug.h" // for NS_ASSERTION
#include "nsISupportsImpl.h" // for Layer::AddRef, etc
#include "nsRect.h" // for mozilla::gfx::IntRect
#include "nsRegion.h" // for nsIntRegion
#include "mozilla/gfx/PathHelpers.h"
using namespace mozilla::gfx;
namespace mozilla {
namespace layers {
class BasicColorLayer : public ColorLayer, public BasicImplData {
public:
explicit BasicColorLayer(BasicLayerManager* aLayerManager)
: ColorLayer(aLayerManager, static_cast<BasicImplData*>(this)) {
MOZ_COUNT_CTOR(BasicColorLayer);
}
protected:
MOZ_COUNTED_DTOR_OVERRIDE(BasicColorLayer)
public:
void SetVisibleRegion(const LayerIntRegion& aRegion) override {
NS_ASSERTION(BasicManager()->InConstruction(),
"Can only set properties in construction phase");
ColorLayer::SetVisibleRegion(aRegion);
}
void Paint(DrawTarget* aDT, const gfx::Point& aDeviceOffset,
Layer* aMaskLayer) override {
if (IsHidden()) {
return;
}
Rect snapped(mBounds.X(), mBounds.Y(), mBounds.Width(), mBounds.Height());
MaybeSnapToDevicePixels(snapped, *aDT, true);
// Clip drawing in case we're using (unbounded) operator source.
aDT->PushClipRect(snapped);
FillRectWithMask(
aDT, aDeviceOffset, snapped, mColor,
DrawOptions(GetEffectiveOpacity(), GetEffectiveOperator(this)),
aMaskLayer);
aDT->PopClip();
}
protected:
BasicLayerManager* BasicManager() {
return static_cast<BasicLayerManager*>(mManager);
}
};
already_AddRefed<ColorLayer> BasicLayerManager::CreateColorLayer() {
NS_ASSERTION(InConstruction(), "Only allowed in construction phase");
RefPtr<ColorLayer> layer = new BasicColorLayer(this);
return layer.forget();
}
} // namespace layers
} // namespace mozilla

Просмотреть файл

@ -1,162 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "BasicContainerLayer.h"
#include <sys/types.h> // for int32_t
#include "BasicLayersImpl.h" // for ToData
#include "basic/BasicImplData.h" // for BasicImplData
#include "basic/BasicLayers.h" // for BasicLayerManager
#include "mozilla/gfx/BaseRect.h" // for BaseRect
#include "mozilla/mozalloc.h" // for operator new
#include "nsCOMPtr.h" // for already_AddRefed
#include "nsISupportsImpl.h" // for Layer::AddRef, etc
#include "nsPoint.h" // for nsIntPoint
#include "nsRegion.h" // for nsIntRegion
#include "ReadbackProcessor.h"
using namespace mozilla::gfx;
namespace mozilla {
namespace layers {
BasicContainerLayer::~BasicContainerLayer() {
ContainerLayer::RemoveAllChildren();
MOZ_COUNT_DTOR(BasicContainerLayer);
}
void BasicContainerLayer::ComputeEffectiveTransforms(
const Matrix4x4& aTransformToSurface) {
// We push groups for container layers if we need to, which always
// are aligned in device space, so it doesn't really matter how we snap
// containers.
Matrix residual;
Matrix4x4 transformToSurface = aTransformToSurface;
bool participate3DCtx = Extend3DContext() || Is3DContextLeaf();
if (!participate3DCtx && GetContentFlags() & CONTENT_BACKFACE_HIDDEN) {
// For backface-hidden layers
transformToSurface.ProjectTo2D();
}
Matrix4x4 idealTransform = GetLocalTransform() * transformToSurface;
if (!participate3DCtx && !(GetContentFlags() & CONTENT_BACKFACE_HIDDEN)) {
// For non-backface-hidden layers,
// 3D components are required to handle CONTENT_BACKFACE_HIDDEN.
idealTransform.ProjectTo2D();
}
if (!idealTransform.CanDraw2D()) {
if (!Extend3DContext()) {
mEffectiveTransform = idealTransform;
ComputeEffectiveTransformsForChildren(Matrix4x4());
ComputeEffectiveTransformForMaskLayers(Matrix4x4());
mUseIntermediateSurface = true;
return;
}
mEffectiveTransform = idealTransform;
ComputeEffectiveTransformsForChildren(idealTransform);
ComputeEffectiveTransformForMaskLayers(idealTransform);
mUseIntermediateSurface = false;
return;
}
// With 2D transform or extended 3D context.
Layer* child = GetFirstChild();
bool hasSingleBlendingChild = false;
if (!HasMultipleChildren() && child) {
hasSingleBlendingChild = child->GetMixBlendMode() != CompositionOp::OP_OVER;
}
/* If we have a single childand it is not blending,, it can just inherit our
* opacity, otherwise we need a PushGroup and we need to mark ourselves as
* using an intermediate surface so our children don't inherit our opacity via
* GetEffectiveOpacity. Having a mask layer always forces our own push group
* Having a blend mode also always forces our own push group
*/
mUseIntermediateSurface =
GetMaskLayer() || GetForceIsolatedGroup() ||
(GetMixBlendMode() != CompositionOp::OP_OVER && HasMultipleChildren()) ||
(GetEffectiveOpacity() != 1.0 &&
((HasMultipleChildren() && !Extend3DContext()) ||
hasSingleBlendingChild));
mEffectiveTransform =
!mUseIntermediateSurface
? idealTransform
: (!(GetContentFlags() & CONTENT_BACKFACE_HIDDEN)
? SnapTransformTranslation(idealTransform, &residual)
: SnapTransformTranslation3D(idealTransform, &residual));
Matrix4x4 childTransformToSurface =
(!mUseIntermediateSurface ||
(mUseIntermediateSurface && !Extend3DContext() /* 2D */))
? idealTransform
: Matrix4x4::From2D(residual);
ComputeEffectiveTransformsForChildren(childTransformToSurface);
ComputeEffectiveTransformForMaskLayers(aTransformToSurface);
}
bool BasicContainerLayer::ChildrenPartitionVisibleRegion(
const gfx::IntRect& aInRect) {
Matrix transform;
if (!GetEffectiveTransform().CanDraw2D(&transform) ||
ThebesMatrix(transform).HasNonIntegerTranslation())
return false;
nsIntPoint offset(int32_t(transform._31), int32_t(transform._32));
gfx::IntRect rect = aInRect.Intersect(
GetLocalVisibleRegion().GetBounds().ToUnknownRect() + offset);
nsIntRegion covered;
for (Layer* l = mFirstChild; l; l = l->GetNextSibling()) {
if (ToData(l)->IsHidden()) continue;
Matrix childTransform;
if (!l->GetEffectiveTransform().CanDraw2D(&childTransform) ||
ThebesMatrix(childTransform).HasNonIntegerTranslation() ||
l->GetEffectiveOpacity() != 1.0)
return false;
nsIntRegion childRegion = l->GetLocalVisibleRegion().ToUnknownRegion();
childRegion.MoveBy(int32_t(childTransform._31),
int32_t(childTransform._32));
childRegion.And(childRegion, rect);
if (l->GetClipRect()) {
childRegion.And(childRegion, l->GetClipRect()->ToUnknownRect() + offset);
}
nsIntRegion intersection;
intersection.And(covered, childRegion);
if (!intersection.IsEmpty()) return false;
covered.Or(covered, childRegion);
}
return covered.Contains(rect);
}
void BasicContainerLayer::Validate(
LayerManager::DrawPaintedLayerCallback aCallback, void* aCallbackData,
ReadbackProcessor* aReadback) {
ReadbackProcessor readback;
if (BasicManager()->IsRetained()) {
readback.BuildUpdates(this);
}
for (Layer* l = mFirstChild; l; l = l->GetNextSibling()) {
BasicImplData* data = ToData(l);
data->Validate(aCallback, aCallbackData, &readback);
if (l->GetMaskLayer()) {
data = ToData(l->GetMaskLayer());
data->Validate(aCallback, aCallbackData, nullptr);
}
}
}
already_AddRefed<ContainerLayer> BasicLayerManager::CreateContainerLayer() {
NS_ASSERTION(InConstruction(), "Only allowed in construction phase");
RefPtr<ContainerLayer> layer = new BasicContainerLayer(this);
return layer.forget();
}
} // namespace layers
} // namespace mozilla

Просмотреть файл

@ -1,103 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef GFX_BASICCONTAINERLAYER_H
#define GFX_BASICCONTAINERLAYER_H
#include "BasicImplData.h" // for BasicImplData
#include "BasicLayers.h" // for BasicLayerManager
#include "Layers.h" // for Layer, ContainerLayer
#include "nsDebug.h" // for NS_ASSERTION
#include "nsISupportsImpl.h" // for MOZ_COUNT_CTOR
#include "nsISupportsUtils.h" // for NS_ADDREF, NS_RELEASE
#include "mozilla/gfx/Rect.h"
namespace mozilla {
namespace layers {
class BasicContainerLayer : public ContainerLayer, public BasicImplData {
public:
explicit BasicContainerLayer(BasicLayerManager* aManager)
: ContainerLayer(aManager, static_cast<BasicImplData*>(this)) {
MOZ_COUNT_CTOR(BasicContainerLayer);
mSupportsComponentAlphaChildren = true;
}
protected:
virtual ~BasicContainerLayer();
public:
void SetVisibleRegion(const LayerIntRegion& aRegion) override {
NS_ASSERTION(BasicManager()->InConstruction(),
"Can only set properties in construction phase");
ContainerLayer::SetVisibleRegion(aRegion);
}
bool InsertAfter(Layer* aChild, Layer* aAfter) override {
if (!BasicManager()->InConstruction()) {
NS_ERROR("Can only set properties in construction phase");
return false;
}
return ContainerLayer::InsertAfter(aChild, aAfter);
}
bool RemoveChild(Layer* aChild) override {
if (!BasicManager()->InConstruction()) {
NS_ERROR("Can only set properties in construction phase");
return false;
}
return ContainerLayer::RemoveChild(aChild);
}
bool RepositionChild(Layer* aChild, Layer* aAfter) override {
if (!BasicManager()->InConstruction()) {
NS_ERROR("Can only set properties in construction phase");
return false;
}
return ContainerLayer::RepositionChild(aChild, aAfter);
}
void ComputeEffectiveTransforms(
const gfx::Matrix4x4& aTransformToSurface) override;
/**
* Returns true when:
* a) no (non-hidden) childrens' visible areas overlap in
* (aInRect intersected with this layer's visible region).
* b) the (non-hidden) childrens' visible areas cover
* (aInRect intersected with this layer's visible region).
* c) this layer and all (non-hidden) children have transforms that are
* translations by integers. aInRect is in the root coordinate system. Child
* layers with opacity do not contribute to the covered area in check b). This
* method can be conservative; it's OK to return false under any
* circumstances.
*/
bool ChildrenPartitionVisibleRegion(const gfx::IntRect& aInRect);
void ForceIntermediateSurface() { mUseIntermediateSurface = true; }
void SetSupportsComponentAlphaChildren(bool aSupports) {
mSupportsComponentAlphaChildren = aSupports;
}
void Validate(LayerManager::DrawPaintedLayerCallback aCallback,
void* aCallbackData, ReadbackProcessor* aReadback) override;
/**
* We don't really have a hard restriction for max layer size, but we pick
* 4096 to avoid excessive memory usage.
*/
int32_t GetMaxLayerSize() override { return 4096; }
protected:
BasicLayerManager* BasicManager() {
return static_cast<BasicLayerManager*>(mManager);
}
};
} // namespace layers
} // namespace mozilla
#endif

Просмотреть файл

@ -1,108 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "BasicLayersImpl.h" // for FillRectWithMask, etc
#include "ImageContainer.h" // for AutoLockImage, etc
#include "ImageLayers.h" // for ImageLayer
#include "Layers.h" // for Layer (ptr only), etc
#include "basic/BasicImplData.h" // for BasicImplData
#include "basic/BasicLayers.h" // for BasicLayerManager
#include "mozilla/mozalloc.h" // for operator new
#include "nsCOMPtr.h" // for already_AddRefed
#include "nsDebug.h" // for NS_ASSERTION
#include "nsISupportsImpl.h" // for gfxPattern::Release, etc
#include "nsRect.h" // for mozilla::gfx::IntRect
#include "nsRegion.h" // for nsIntRegion
#include "mozilla/gfx/Point.h" // for IntSize
using namespace mozilla::gfx;
namespace mozilla::layers {
class BasicImageLayer : public ImageLayer, public BasicImplData {
public:
explicit BasicImageLayer(BasicLayerManager* aLayerManager)
: ImageLayer(aLayerManager, static_cast<BasicImplData*>(this)),
mSize(-1, -1) {
MOZ_COUNT_CTOR(BasicImageLayer);
}
protected:
MOZ_COUNTED_DTOR_OVERRIDE(BasicImageLayer)
public:
void SetVisibleRegion(const LayerIntRegion& aRegion) override {
NS_ASSERTION(BasicManager()->InConstruction(),
"Can only set properties in construction phase");
ImageLayer::SetVisibleRegion(aRegion);
}
void Paint(DrawTarget* aDT, const gfx::Point& aDeviceOffset,
Layer* aMaskLayer) override;
already_AddRefed<SourceSurface> GetAsSourceSurface() override;
protected:
BasicLayerManager* BasicManager() {
return static_cast<BasicLayerManager*>(mManager);
}
gfx::IntSize mSize;
};
void BasicImageLayer::Paint(DrawTarget* aDT, const gfx::Point& aDeviceOffset,
Layer* aMaskLayer) {
if (IsHidden() || !mContainer) {
return;
}
RefPtr<ImageFactory> originalIF = mContainer->GetImageFactory();
mContainer->SetImageFactory(mManager->IsCompositingCheap()
? nullptr
: BasicManager()->GetImageFactory());
AutoLockImage autoLock(mContainer);
Image* image = autoLock.GetImage(BasicManager()->GetCompositionTime());
if (!image) {
mContainer->SetImageFactory(originalIF);
return;
}
RefPtr<gfx::SourceSurface> surface = image->GetAsSourceSurface();
if (!surface || !surface->IsValid()) {
mContainer->SetImageFactory(originalIF);
return;
}
gfx::IntSize size = mSize = surface->GetSize();
FillRectWithMask(
aDT, aDeviceOffset, Rect(0, 0, size.width, size.height), surface,
mSamplingFilter,
DrawOptions(GetEffectiveOpacity(), GetEffectiveOperator(this)),
aMaskLayer);
mContainer->SetImageFactory(originalIF);
}
already_AddRefed<SourceSurface> BasicImageLayer::GetAsSourceSurface() {
if (!mContainer) {
return nullptr;
}
AutoLockImage lockImage(mContainer);
Image* image = lockImage.GetImage();
if (!image) {
return nullptr;
}
return image->GetAsSourceSurface();
}
already_AddRefed<ImageLayer> BasicLayerManager::CreateImageLayer() {
NS_ASSERTION(InConstruction(), "Only allowed in construction phase");
RefPtr<ImageLayer> layer = new BasicImageLayer(this);
return layer.forget();
}
} // namespace mozilla::layers

Просмотреть файл

@ -1,180 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include <stdint.h> // for uint8_t, uint32_t
#include "BasicLayers.h" // for BasicLayerManager
#include "ImageContainer.h" // for PlanarYCbCrImage, etc
#include "ImageTypes.h" // for ImageFormat, etc
#include "cairo.h" // for cairo_user_data_key_t
#include "gfxASurface.h" // for gfxASurface, etc
#include "gfxPlatform.h" // for gfxPlatform, gfxImageFormat
#include "gfxUtils.h" // for gfxUtils
#include "mozilla/CheckedInt.h"
#include "mozilla/mozalloc.h" // for operator delete[], etc
#include "mozilla/RefPtr.h"
#include "mozilla/UniquePtr.h"
#include "nsCOMPtr.h" // for already_AddRefed
#include "nsDebug.h" // for NS_ERROR, NS_ASSERTION
#include "nsISupportsImpl.h" // for Image::Release, etc
#include "nsThreadUtils.h" // for NS_IsMainThread
#include "mozilla/gfx/Point.h" // for IntSize
#include "mozilla/gfx/DataSurfaceHelpers.h"
#include "gfx2DGlue.h"
#include "YCbCrUtils.h" // for YCbCr conversions
namespace mozilla {
namespace layers {
class BasicPlanarYCbCrImage : public RecyclingPlanarYCbCrImage {
public:
BasicPlanarYCbCrImage(const gfx::IntSize& aScaleHint,
gfxImageFormat aOffscreenFormat,
BufferRecycleBin* aRecycleBin)
: RecyclingPlanarYCbCrImage(aRecycleBin),
mScaleHint(aScaleHint),
mStride(0),
mDelayedConversion(false) {
SetOffscreenFormat(aOffscreenFormat);
}
~BasicPlanarYCbCrImage() {
if (mDecodedBuffer) {
// Right now this only happens if the Image was never drawn, otherwise
// this will have been tossed away at surface destruction.
mRecycleBin->RecycleBuffer(std::move(mDecodedBuffer),
mSize.height * mStride);
}
}
virtual bool CopyData(const Data& aData) override;
virtual void SetDelayedConversion(bool aDelayed) override {
mDelayedConversion = aDelayed;
}
already_AddRefed<gfx::SourceSurface> GetAsSourceSurface() override;
virtual size_t SizeOfIncludingThis(
MallocSizeOf aMallocSizeOf) const override {
return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
}
virtual size_t SizeOfExcludingThis(
MallocSizeOf aMallocSizeOf) const override {
size_t size = RecyclingPlanarYCbCrImage::SizeOfExcludingThis(aMallocSizeOf);
size += aMallocSizeOf(mDecodedBuffer.get());
return size;
}
private:
UniquePtr<uint8_t[]> mDecodedBuffer;
gfx::IntSize mScaleHint;
int mStride;
bool mDelayedConversion;
};
class BasicImageFactory : public ImageFactory {
public:
BasicImageFactory() = default;
virtual RefPtr<PlanarYCbCrImage> CreatePlanarYCbCrImage(
const gfx::IntSize& aScaleHint, BufferRecycleBin* aRecycleBin) override {
return new BasicPlanarYCbCrImage(
aScaleHint, gfxPlatform::GetPlatform()->GetOffscreenFormat(),
aRecycleBin);
}
};
bool BasicPlanarYCbCrImage::CopyData(const Data& aData) {
RecyclingPlanarYCbCrImage::CopyData(aData);
if (mDelayedConversion) {
return false;
}
// Do some sanity checks to prevent integer overflow
if (aData.mYSize.width > PlanarYCbCrImage::MAX_DIMENSION ||
aData.mYSize.height > PlanarYCbCrImage::MAX_DIMENSION) {
NS_ERROR("Illegal image source width or height");
return false;
}
gfx::SurfaceFormat format =
gfx::ImageFormatToSurfaceFormat(GetOffscreenFormat());
gfx::IntSize size(mScaleHint);
gfx::GetYCbCrToRGBDestFormatAndSize(aData, format, size);
if (size.width > PlanarYCbCrImage::MAX_DIMENSION ||
size.height > PlanarYCbCrImage::MAX_DIMENSION) {
NS_ERROR("Illegal image dest width or height");
return false;
}
mStride = gfx::StrideForFormatAndWidth(format, size.width);
mozilla::CheckedInt32 requiredBytes =
mozilla::CheckedInt32(size.height) * mozilla::CheckedInt32(mStride);
if (!requiredBytes.isValid()) {
// invalid size
return false;
}
mDecodedBuffer = AllocateBuffer(requiredBytes.value());
if (!mDecodedBuffer) {
// out of memory
return false;
}
gfx::ConvertYCbCrToRGB(aData, format, size, mDecodedBuffer.get(), mStride);
SetOffscreenFormat(gfx::SurfaceFormatToImageFormat(format));
mSize = size;
return true;
}
already_AddRefed<gfx::SourceSurface>
BasicPlanarYCbCrImage::GetAsSourceSurface() {
NS_ASSERTION(NS_IsMainThread(), "Must be main thread");
if (mSourceSurface) {
RefPtr<gfx::SourceSurface> surface(mSourceSurface);
return surface.forget();
}
if (!mDecodedBuffer) {
return PlanarYCbCrImage::GetAsSourceSurface();
}
gfxImageFormat format = GetOffscreenFormat();
RefPtr<gfx::SourceSurface> surface;
{
// Create a DrawTarget so that we can own the data inside mDecodeBuffer.
// We create the target out of mDecodedBuffer, and get a snapshot from it.
// The draw target is destroyed on scope exit and the surface owns the data.
RefPtr<gfx::DrawTarget> drawTarget = gfxPlatform::CreateDrawTargetForData(
mDecodedBuffer.get(), mSize, mStride,
gfx::ImageFormatToSurfaceFormat(format));
if (!drawTarget) {
return nullptr;
}
surface = drawTarget->Snapshot();
}
mRecycleBin->RecycleBuffer(std::move(mDecodedBuffer), mSize.height * mStride);
mSourceSurface = surface;
return surface.forget();
}
ImageFactory* BasicLayerManager::GetImageFactory() {
if (!mFactory) {
mFactory = new BasicImageFactory();
}
return mFactory.get();
}
} // namespace layers
} // namespace mozilla

Просмотреть файл

@ -1,973 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include <stdint.h> // for uint32_t
#include <stdlib.h> // for rand, RAND_MAX
#include <sys/types.h> // for int32_t
#include <stack> // for stack
#include "BasicContainerLayer.h" // for BasicContainerLayer
#include "BasicLayersImpl.h" // for ToData, BasicReadbackLayer, etc
#include "ImageContainer.h" // for ImageFactory
#include "Layers.h" // for Layer, ContainerLayer, etc
#include "ReadbackLayer.h" // for ReadbackLayer
#include "ReadbackProcessor.h" // for ReadbackProcessor
#include "RenderTrace.h" // for RenderTraceLayers, etc
#include "basic/BasicImplData.h" // for BasicImplData
#include "basic/BasicLayers.h" // for BasicLayerManager, etc
#include "gfxASurface.h" // for gfxASurface, etc
#include "gfxContext.h" // for gfxContext, etc
#include "gfxImageSurface.h" // for gfxImageSurface
#include "gfxMatrix.h" // for gfxMatrix
#include "gfxPlatform.h" // for gfxPlatform
#include "gfxPoint.h" // for IntSize, gfxPoint
#include "gfxRect.h" // for gfxRect
#include "gfxUtils.h" // for gfxUtils
#include "gfx2DGlue.h" // for thebes --> moz2d transition
#include "mozilla/Assertions.h" // for MOZ_ASSERT, etc
#include "mozilla/ProfilerLabels.h"
#include "mozilla/StaticPrefs_nglayout.h"
#include "mozilla/WidgetUtils.h" // for ScreenRotation
#include "mozilla/gfx/2D.h" // for DrawTarget
#include "mozilla/gfx/BasePoint.h" // for BasePoint
#include "mozilla/gfx/BaseRect.h" // for BaseRect
#include "mozilla/gfx/Matrix.h" // for Matrix
#include "mozilla/gfx/PathHelpers.h"
#include "mozilla/gfx/Rect.h" // for IntRect, Rect
#include "mozilla/layers/BSPTree.h"
#include "mozilla/layers/LayersTypes.h" // for BufferMode::BUFFER_NONE, etc
#include "mozilla/mozalloc.h" // for operator new
#include "nsCOMPtr.h" // for already_AddRefed
#include "nsDebug.h" // for NS_ASSERTION, etc
#include "nsISupportsImpl.h" // for gfxContext::Release, etc
#include "nsLayoutUtils.h" // for nsLayoutUtils
#include "nsPoint.h" // for nsIntPoint
#include "nsRect.h" // for mozilla::gfx::IntRect
#include "nsRegion.h" // for nsIntRegion, etc
#include "nsTArray.h" // for AutoTArray
#include "TreeTraversal.h" // for ForEachNode
class nsIWidget;
namespace mozilla {
namespace layers {
using namespace mozilla::gfx;
/**
* Clips to the smallest device-pixel-aligned rectangle containing aRect
* in user space.
* Returns true if the clip is "perfect", i.e. we actually clipped exactly to
* aRect.
*/
static bool ClipToContain(gfxContext* aContext, const IntRect& aRect) {
gfxRect userRect(aRect.X(), aRect.Y(), aRect.Width(), aRect.Height());
gfxRect deviceRect = aContext->UserToDevice(userRect);
deviceRect.RoundOut();
Matrix currentMatrix = aContext->CurrentMatrix();
aContext->SetMatrix(Matrix());
aContext->NewPath();
aContext->Rectangle(deviceRect);
aContext->Clip();
aContext->SetMatrix(currentMatrix);
return aContext->DeviceToUser(deviceRect).IsEqualInterior(userRect);
}
bool BasicLayerManager::PushGroupForLayer(gfxContext* aContext, Layer* aLayer,
const nsIntRegion& aRegion,
PushedGroup& aGroupResult) {
aGroupResult.mVisibleRegion = aRegion;
aGroupResult.mFinalTarget = aContext;
aGroupResult.mOperator = GetEffectiveOperator(aLayer);
aGroupResult.mOpacity = aLayer->GetEffectiveOpacity();
// If we need to call PushGroup, we should clip to the smallest possible
// area first to minimize the size of the temporary surface.
bool didCompleteClip = ClipToContain(aContext, aRegion.GetBounds());
bool canPushGroup =
aGroupResult.mOperator == CompositionOp::OP_OVER ||
(aGroupResult.mOperator == CompositionOp::OP_SOURCE &&
(aLayer->CanUseOpaqueSurface() ||
aLayer->GetContentFlags() & Layer::CONTENT_COMPONENT_ALPHA));
if (!canPushGroup) {
aContext->Save();
// Restore() is called in PopGroupForLayer
// if group.mFinalTarget != group.mGroupTarget
gfxUtils::ClipToRegion(aGroupResult.mFinalTarget,
aGroupResult.mVisibleRegion);
// PushGroup/PopGroup do not support non operator over.
gfxRect rect = aContext->GetClipExtents(gfxContext::eDeviceSpace);
rect.RoundOut();
IntRect surfRect;
ToRect(rect).ToIntRect(&surfRect);
if (!surfRect.IsEmpty()) {
RefPtr<DrawTarget> dt;
if (aContext->GetDrawTarget()->CanCreateSimilarDrawTarget(
surfRect.Size(), SurfaceFormat::B8G8R8A8)) {
dt = aContext->GetDrawTarget()->CreateSimilarDrawTarget(
surfRect.Size(), SurfaceFormat::B8G8R8A8);
}
RefPtr<gfxContext> ctx =
gfxContext::CreateOrNull(dt, ToRect(rect).TopLeft());
if (!ctx) {
gfxCriticalNote
<< "BasicLayerManager context problem in PushGroupForLayer "
<< gfx::hexa(dt);
aContext->Restore();
return false;
}
ctx->SetMatrix(aContext->CurrentMatrix());
aGroupResult.mGroupOffset = surfRect.TopLeft();
aGroupResult.mGroupTarget = ctx;
aGroupResult.mMaskSurface =
GetMaskForLayer(aLayer, &aGroupResult.mMaskTransform);
return true;
}
aContext->Restore();
}
Matrix maskTransform;
RefPtr<SourceSurface> maskSurf = GetMaskForLayer(aLayer, &maskTransform);
if (maskSurf) {
// The returned transform will transform the mask to device space on the
// destination. Since the User->Device space transform will be applied
// to the mask by PopGroupAndBlend we need to adjust the transform to
// transform the mask to user space.
Matrix currentTransform = aGroupResult.mFinalTarget->CurrentMatrix();
currentTransform.Invert();
maskTransform = maskTransform * currentTransform;
}
if (aLayer->CanUseOpaqueSurface() &&
((didCompleteClip && aRegion.GetNumRects() == 1) ||
!aContext->CurrentMatrix().HasNonIntegerTranslation())) {
// If the layer is opaque in its visible region we can push a
// gfxContentType::COLOR group. We need to make sure that only pixels inside
// the layer's visible region are copied back to the destination. Remember
// if we've already clipped precisely to the visible region.
aGroupResult.mNeedsClipToVisibleRegion =
!didCompleteClip || aRegion.GetNumRects() > 1;
if (aGroupResult.mNeedsClipToVisibleRegion) {
aGroupResult.mFinalTarget->Save();
gfxUtils::ClipToRegion(aGroupResult.mFinalTarget,
aGroupResult.mVisibleRegion);
}
aContext->PushGroupForBlendBack(
gfxContentType::COLOR, aGroupResult.mOpacity, maskSurf, maskTransform);
} else {
if (aLayer->GetContentFlags() & Layer::CONTENT_COMPONENT_ALPHA) {
aContext->PushGroupAndCopyBackground(gfxContentType::COLOR_ALPHA,
aGroupResult.mOpacity, maskSurf,
maskTransform);
} else {
aContext->PushGroupForBlendBack(gfxContentType::COLOR_ALPHA,
aGroupResult.mOpacity, maskSurf,
maskTransform);
}
}
aGroupResult.mGroupTarget = aGroupResult.mFinalTarget;
return true;
}
void BasicLayerManager::PopGroupForLayer(PushedGroup& group) {
if (group.mFinalTarget == group.mGroupTarget) {
group.mFinalTarget->PopGroupAndBlend();
if (group.mNeedsClipToVisibleRegion) {
group.mFinalTarget->Restore();
}
return;
}
DrawTarget* dt = group.mFinalTarget->GetDrawTarget();
RefPtr<DrawTarget> sourceDT = group.mGroupTarget->GetDrawTarget();
group.mGroupTarget = nullptr;
RefPtr<SourceSurface> src = sourceDT->Snapshot();
if (group.mMaskSurface) {
Point finalOffset = group.mFinalTarget->GetDeviceOffset();
dt->SetTransform(group.mMaskTransform * Matrix::Translation(-finalOffset));
Matrix surfTransform = group.mMaskTransform;
surfTransform.Invert();
dt->MaskSurface(SurfacePattern(src, ExtendMode::CLAMP,
surfTransform * Matrix::Translation(
group.mGroupOffset.x,
group.mGroupOffset.y)),
group.mMaskSurface, Point(0, 0),
DrawOptions(group.mOpacity, group.mOperator));
} else {
// For now this is required since our group offset is in device space of the
// final target, context but that may still have its own device offset. Once
// PushGroup/PopGroup logic is migrated to DrawTargets this can go as
// gfxContext::GetDeviceOffset will essentially always become null.
dt->SetTransform(
Matrix::Translation(-group.mFinalTarget->GetDeviceOffset()));
dt->DrawSurface(src,
Rect(group.mGroupOffset.x, group.mGroupOffset.y,
src->GetSize().width, src->GetSize().height),
Rect(0, 0, src->GetSize().width, src->GetSize().height),
DrawSurfaceOptions(SamplingFilter::POINT),
DrawOptions(group.mOpacity, group.mOperator));
}
if (group.mNeedsClipToVisibleRegion) {
dt->PopClip();
}
group.mFinalTarget->Restore();
}
static IntRect ToInsideIntRect(const gfxRect& aRect) {
return IntRect::RoundIn(aRect.X(), aRect.Y(), aRect.Width(), aRect.Height());
}
// A context helper for BasicLayerManager::PaintLayer() that holds all the
// painting context together in a data structure so it can be easily passed
// around. It also uses ensures that the Transform and Opaque rect are restored
// to their former state on destruction.
class PaintLayerContext {
public:
PaintLayerContext(gfxContext* aTarget, Layer* aLayer,
LayerManager::DrawPaintedLayerCallback aCallback,
void* aCallbackData)
: mTarget(aTarget),
mTargetMatrixSR(aTarget),
mLayer(aLayer),
mCallback(aCallback),
mCallbackData(aCallbackData),
mPushedOpaqueRect(false) {}
~PaintLayerContext() {
// Matrix is restored by mTargetMatrixSR
if (mPushedOpaqueRect) {
ClearOpaqueRect();
}
}
// Gets the effective transform and returns true if it is a 2D
// transform.
bool Setup2DTransform() {
// Will return an identity matrix for 3d transforms.
return mLayer->GetEffectiveTransformForBuffer().CanDraw2D(&mTransform);
}
// Applies the effective transform if it's 2D. If it's a 3D transform then
// it applies an identity.
void Apply2DTransform() { mTarget->SetMatrix(mTransform); }
// Set the opaque rect to match the bounds of the visible region.
void AnnotateOpaqueRect() {
const nsIntRegion visibleRegion =
mLayer->GetLocalVisibleRegion().ToUnknownRegion();
const IntRect& bounds = visibleRegion.GetBounds();
DrawTarget* dt = mTarget->GetDrawTarget();
const IntRect& targetOpaqueRect = dt->GetOpaqueRect();
// Try to annotate currentSurface with a region of pixels that have been
// (or will be) painted opaque, if no such region is currently set.
if (targetOpaqueRect.IsEmpty() && visibleRegion.GetNumRects() == 1 &&
(mLayer->GetContentFlags() & Layer::CONTENT_OPAQUE) &&
!mTransform.HasNonAxisAlignedTransform()) {
gfx::Rect opaqueRect = dt->GetTransform().TransformBounds(
gfx::Rect(bounds.X(), bounds.Y(), bounds.Width(), bounds.Height()));
opaqueRect.RoundIn();
IntRect intOpaqueRect;
if (opaqueRect.ToIntRect(&intOpaqueRect)) {
mTarget->GetDrawTarget()->SetOpaqueRect(intOpaqueRect);
mPushedOpaqueRect = true;
}
}
}
// Clear the Opaque rect. Although this doesn't really restore it to it's
// previous state it will happen on the exit path of the PaintLayer() so when
// painting is complete the opaque rect qill be clear.
void ClearOpaqueRect() { mTarget->GetDrawTarget()->SetOpaqueRect(IntRect()); }
gfxContext* mTarget;
gfxContextMatrixAutoSaveRestore mTargetMatrixSR;
Layer* mLayer;
LayerManager::DrawPaintedLayerCallback mCallback;
void* mCallbackData;
Matrix mTransform;
bool mPushedOpaqueRect;
};
BasicLayerManager::BasicLayerManager(nsIWidget* aWidget)
: mPhase(PHASE_NONE),
mWidget(aWidget),
mDoubleBuffering(BufferMode::BUFFER_NONE),
mType(BLM_WIDGET),
mUsingDefaultTarget(false),
mTransactionIncomplete(false),
mCompositorMightResample(false) {
MOZ_COUNT_CTOR(BasicLayerManager);
NS_ASSERTION(aWidget, "Must provide a widget");
}
BasicLayerManager::BasicLayerManager(BasicLayerManagerType aType)
: mPhase(PHASE_NONE),
mWidget(nullptr),
mDoubleBuffering(BufferMode::BUFFER_NONE),
mType(aType),
mUsingDefaultTarget(false),
mTransactionIncomplete(false),
mCompositorMightResample(false) {
MOZ_COUNT_CTOR(BasicLayerManager);
MOZ_ASSERT(mType != BLM_WIDGET);
}
BasicLayerManager::~BasicLayerManager() {
NS_ASSERTION(!InTransaction(), "Died during transaction?");
ClearCachedResources();
mRoot = nullptr;
MOZ_COUNT_DTOR(BasicLayerManager);
}
void BasicLayerManager::SetDefaultTarget(gfxContext* aContext) {
NS_ASSERTION(!InTransaction(), "Must set default target outside transaction");
mDefaultTarget = aContext;
}
void BasicLayerManager::SetDefaultTargetConfiguration(
BufferMode aDoubleBuffering, ScreenRotation aRotation) {
mDoubleBuffering = aDoubleBuffering;
}
bool BasicLayerManager::BeginTransaction(const nsCString& aURL) {
mInTransaction = true;
mUsingDefaultTarget = true;
return BeginTransactionWithTarget(mDefaultTarget, aURL);
}
bool BasicLayerManager::BeginTransactionWithTarget(gfxContext* aTarget,
const nsCString& aURL) {
mInTransaction = true;
#ifdef MOZ_LAYERS_HAVE_LOG
MOZ_LAYERS_LOG(("[----- BeginTransaction"));
Log();
#endif
NS_ASSERTION(!InTransaction(), "Nested transactions not allowed");
mPhase = PHASE_CONSTRUCTION;
mTarget = aTarget;
return true;
}
static void TransformIntRect(IntRect& aRect, const Matrix& aMatrix,
IntRect (*aRoundMethod)(const gfxRect&)) {
Rect gr = Rect(aRect.X(), aRect.Y(), aRect.Width(), aRect.Height());
gr = aMatrix.TransformBounds(gr);
aRect = (*aRoundMethod)(ThebesRect(gr));
}
/**
* This function assumes that GetEffectiveTransform transforms
* all layers to the same coordinate system (the "root coordinate system").
* It can't be used as is by accelerated layers because of intermediate
* surfaces. This must set the hidden flag to true or false on *all* layers in
* the subtree. It also sets the operator for all layers to "OVER", and call
* SetDrawAtomically(false).
* It clears mClipToVisibleRegion on all layers.
* @param aClipRect the cliprect, in the root coordinate system. We assume
* that any layer drawing is clipped to this rect. It is therefore not
* allowed to add to the opaque region outside that rect.
* @param aDirtyRect the dirty rect that will be painted, in the root
* coordinate system. Layers outside this rect should be hidden.
* @param aOpaqueRegion the opaque region covering aLayer, in the
* root coordinate system.
*/
enum {
ALLOW_OPAQUE = 0x01,
};
static void MarkLayersHidden(Layer* aLayer, const IntRect& aClipRect,
const IntRect& aDirtyRect,
nsIntRegion& aOpaqueRegion, uint32_t aFlags) {
IntRect newClipRect(aClipRect);
uint32_t newFlags = aFlags;
// Allow aLayer or aLayer's descendants to cover underlying layers
// only if it's opaque.
if (aLayer->GetOpacity() != 1.0f) {
newFlags &= ~ALLOW_OPAQUE;
}
{
const Maybe<ParentLayerIntRect>& clipRect = aLayer->GetLocalClipRect();
if (clipRect) {
IntRect cr = clipRect->ToUnknownRect();
// clipRect is in the container's coordinate system. Get it into the
// global coordinate system.
if (aLayer->GetParent()) {
Matrix tr;
if (aLayer->GetParent()->GetEffectiveTransform().CanDraw2D(&tr)) {
// Clip rect is applied after aLayer's transform, i.e., in the
// coordinate system of aLayer's parent.
TransformIntRect(cr, tr, ToInsideIntRect);
} else {
cr.SetRect(0, 0, 0, 0);
}
}
newClipRect.IntersectRect(newClipRect, cr);
}
}
BasicImplData* data = ToData(aLayer);
data->SetOperator(CompositionOp::OP_OVER);
data->SetClipToVisibleRegion(false);
data->SetDrawAtomically(false);
if (!aLayer->AsContainerLayer()) {
Matrix transform;
if (!aLayer->GetEffectiveTransform().CanDraw2D(&transform)) {
data->SetHidden(false);
return;
}
nsIntRegion region = aLayer->GetLocalVisibleRegion().ToUnknownRegion();
IntRect r = region.GetBounds();
TransformIntRect(r, transform, ToOutsideIntRect);
r.IntersectRect(r, aDirtyRect);
data->SetHidden(aOpaqueRegion.Contains(r));
// Allow aLayer to cover underlying layers only if aLayer's
// content is opaque
if ((aLayer->GetContentFlags() & Layer::CONTENT_OPAQUE) &&
(newFlags & ALLOW_OPAQUE)) {
for (auto iter = region.RectIter(); !iter.Done(); iter.Next()) {
r = iter.Get();
TransformIntRect(r, transform, ToInsideIntRect);
r.IntersectRect(r, newClipRect);
aOpaqueRegion.Or(aOpaqueRegion, r);
}
}
} else {
Layer* child = aLayer->GetLastChild();
bool allHidden = true;
for (; child; child = child->GetPrevSibling()) {
MarkLayersHidden(child, newClipRect, aDirtyRect, aOpaqueRegion, newFlags);
if (!ToData(child)->IsHidden()) {
allHidden = false;
}
}
data->SetHidden(allHidden);
}
}
/**
* This function assumes that GetEffectiveTransform transforms
* all layers to the same coordinate system (the "root coordinate system").
* MarkLayersHidden must be called before calling this.
* @param aVisibleRect the rectangle of aLayer that is visible (i.e. not
* clipped and in the dirty rect), in the root coordinate system.
*/
static void ApplyDoubleBuffering(Layer* aLayer, const IntRect& aVisibleRect) {
BasicImplData* data = ToData(aLayer);
if (data->IsHidden()) return;
IntRect newVisibleRect(aVisibleRect);
{
const Maybe<ParentLayerIntRect>& clipRect = aLayer->GetLocalClipRect();
if (clipRect) {
IntRect cr = clipRect->ToUnknownRect();
// clipRect is in the container's coordinate system. Get it into the
// global coordinate system.
if (aLayer->GetParent()) {
Matrix tr;
if (aLayer->GetParent()->GetEffectiveTransform().CanDraw2D(&tr)) {
NS_ASSERTION(!ThebesMatrix(tr).HasNonIntegerTranslation(),
"Parent can only have an integer translation");
cr += nsIntPoint(int32_t(tr._31), int32_t(tr._32));
} else {
NS_ERROR("Parent can only have an integer translation");
}
}
newVisibleRect.IntersectRect(newVisibleRect, cr);
}
}
BasicContainerLayer* container =
static_cast<BasicContainerLayer*>(aLayer->AsContainerLayer());
// Layers that act as their own backbuffers should be drawn to the destination
// using OP_SOURCE to ensure that alpha values in a transparent window are
// cleared. This can also be faster than OP_OVER.
if (!container) {
data->SetOperator(CompositionOp::OP_SOURCE);
data->SetDrawAtomically(true);
} else {
if (container->UseIntermediateSurface() ||
!container->ChildrenPartitionVisibleRegion(newVisibleRect)) {
// We need to double-buffer this container.
data->SetOperator(CompositionOp::OP_SOURCE);
container->ForceIntermediateSurface();
} else {
// Tell the children to clip to their visible regions so our assumption
// that they don't paint outside their visible regions is valid!
for (Layer* child = aLayer->GetFirstChild(); child;
child = child->GetNextSibling()) {
ToData(child)->SetClipToVisibleRegion(true);
ApplyDoubleBuffering(child, newVisibleRect);
}
}
}
}
void BasicLayerManager::EndTransaction(DrawPaintedLayerCallback aCallback,
void* aCallbackData,
EndTransactionFlags aFlags) {
mInTransaction = false;
EndTransactionInternal(aCallback, aCallbackData, aFlags);
}
void BasicLayerManager::AbortTransaction() {
NS_ASSERTION(InConstruction(), "Should be in construction phase");
mPhase = PHASE_NONE;
mUsingDefaultTarget = false;
mInTransaction = false;
}
bool BasicLayerManager::EndTransactionInternal(
DrawPaintedLayerCallback aCallback, void* aCallbackData,
EndTransactionFlags aFlags) {
AUTO_PROFILER_LABEL("BasicLayerManager::EndTransactionInternal", GRAPHICS);
#ifdef MOZ_LAYERS_HAVE_LOG
MOZ_LAYERS_LOG((" ----- (beginning paint)"));
Log();
#endif
NS_ASSERTION(InConstruction(), "Should be in construction phase");
mPhase = PHASE_DRAWING;
SetCompositionTime(TimeStamp::Now());
RenderTraceLayers(mRoot, "FF00");
mTransactionIncomplete = false;
std::unordered_set<ScrollableLayerGuid::ViewID> scrollIdsUpdated;
if (mRoot) {
if (aFlags & END_NO_COMPOSITE) {
// Apply pending tree updates before recomputing effective
// properties.
scrollIdsUpdated = mRoot->ApplyPendingUpdatesToSubtree();
}
// Need to do this before we call ApplyDoubleBuffering,
// which depends on correct effective transforms
if (mTarget) {
mSnapEffectiveTransforms =
!mTarget->GetDrawTarget()->GetUserData(&sDisablePixelSnapping);
} else {
mSnapEffectiveTransforms = true;
}
mRoot->ComputeEffectiveTransforms(
mTarget ? Matrix4x4::From2D(mTarget->CurrentMatrix()) : Matrix4x4());
ToData(mRoot)->Validate(aCallback, aCallbackData, nullptr);
if (mRoot->GetMaskLayer()) {
ToData(mRoot->GetMaskLayer())
->Validate(aCallback, aCallbackData, nullptr);
}
}
if (mTarget && mRoot && !(aFlags & END_NO_IMMEDIATE_REDRAW) &&
!(aFlags & END_NO_COMPOSITE)) {
IntRect clipRect =
ToOutsideIntRect(mTarget->GetClipExtents(gfxContext::eDeviceSpace));
if (IsRetained()) {
nsIntRegion region;
MarkLayersHidden(mRoot, clipRect, clipRect, region, ALLOW_OPAQUE);
if (mUsingDefaultTarget && mDoubleBuffering != BufferMode::BUFFER_NONE) {
ApplyDoubleBuffering(mRoot, clipRect);
}
}
PaintLayer(mTarget, mRoot, aCallback, aCallbackData);
if (!mRegionToClear.IsEmpty()) {
for (auto iter = mRegionToClear.RectIter(); !iter.Done(); iter.Next()) {
const IntRect& r = iter.Get();
mTarget->GetDrawTarget()->ClearRect(
Rect(r.X(), r.Y(), r.Width(), r.Height()));
}
}
if (mWidget) {
FlashWidgetUpdateArea(mTarget);
}
RecordFrame();
if (!mTransactionIncomplete) {
// Clear out target if we have a complete transaction.
mTarget = nullptr;
}
}
if (mRoot) {
mAnimationReadyTime = TimeStamp::Now();
mRoot->StartPendingAnimations(mAnimationReadyTime);
// Once we're sure we're not going to fall back to a full paint,
// notify the scroll frames which had pending updates.
if (!mTransactionIncomplete) {
for (ScrollableLayerGuid::ViewID scrollId : scrollIdsUpdated) {
nsLayoutUtils::NotifyPaintSkipTransaction(scrollId);
}
}
}
#ifdef MOZ_LAYERS_HAVE_LOG
Log();
MOZ_LAYERS_LOG(("]----- EndTransaction"));
#endif
// Go back to the construction phase if the transaction isn't complete.
// Layout will update the layer tree and call EndTransaction().
mPhase = mTransactionIncomplete ? PHASE_CONSTRUCTION : PHASE_NONE;
if (!mTransactionIncomplete) {
// This is still valid if the transaction was incomplete.
mUsingDefaultTarget = false;
}
NS_ASSERTION(!aCallback || !mTransactionIncomplete,
"If callback is not null, transaction must be complete");
// XXX - We should probably assert here that for an incomplete transaction
// out target is the default target.
return !mTransactionIncomplete;
}
void BasicLayerManager::FlashWidgetUpdateArea(gfxContext* aContext) {
if (StaticPrefs::nglayout_debug_widget_update_flashing()) {
float r = float(rand()) / float(RAND_MAX);
float g = float(rand()) / float(RAND_MAX);
float b = float(rand()) / float(RAND_MAX);
aContext->SetDeviceColor(DeviceColor(r, g, b, 0.2f));
aContext->Paint();
}
}
bool BasicLayerManager::EndEmptyTransaction(EndTransactionFlags aFlags) {
mInTransaction = false;
if (!mRoot) {
return false;
}
return EndTransactionInternal(nullptr, nullptr, aFlags);
}
void BasicLayerManager::SetRoot(Layer* aLayer) {
NS_ASSERTION(aLayer, "Root can't be null");
NS_ASSERTION(aLayer->Manager() == this, "Wrong manager");
NS_ASSERTION(InConstruction(), "Only allowed in construction phase");
mRoot = aLayer;
}
void BasicLayerManager::PaintSelfOrChildren(PaintLayerContext& aPaintContext,
gfxContext* aGroupTarget) {
MOZ_ASSERT(aGroupTarget);
BasicImplData* data = ToData(aPaintContext.mLayer);
/* Only paint ourself, or our children - This optimization relies on this! */
Layer* child = aPaintContext.mLayer->GetFirstChild();
if (!child) {
if (aPaintContext.mLayer->AsPaintedLayer()) {
data->PaintThebes(aGroupTarget, aPaintContext.mLayer->GetMaskLayer(),
aPaintContext.mCallback, aPaintContext.mCallbackData);
} else {
data->Paint(aGroupTarget->GetDrawTarget(),
aGroupTarget->GetDeviceOffset(),
aPaintContext.mLayer->GetMaskLayer());
}
} else {
ContainerLayer* container =
static_cast<ContainerLayer*>(aPaintContext.mLayer);
nsTArray<LayerPolygon> children = container->SortChildrenBy3DZOrder(
ContainerLayer::SortMode::WITHOUT_GEOMETRY);
for (uint32_t i = 0; i < children.Length(); i++) {
Layer* layer = children.ElementAt(i).data;
if (layer->IsBackfaceHidden()) {
continue;
}
if (!layer->AsContainerLayer() && !layer->IsVisible()) {
continue;
}
PaintLayer(aGroupTarget, layer, aPaintContext.mCallback,
aPaintContext.mCallbackData);
if (mTransactionIncomplete) break;
}
}
}
void 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 ---
// that could cause flicker. Double-buffering is implemented using a
// temporary surface for one or more container layers, so we need to stop
// those temporary surfaces from being composited to aTarget.
// ApplyDoubleBuffering guarantees that this container layer can't
// intersect any other leaf layers, so if the transaction is not yet marked
// incomplete, the contents of this container layer are the final contents
// for the window.
if (!mTransactionIncomplete) {
if (aNeedsClipToVisibleRegion) {
gfxUtils::ClipToRegion(
aPaintContext.mTarget,
aPaintContext.mLayer->GetLocalVisibleRegion().ToUnknownRegion());
}
CompositionOp op = GetEffectiveOperator(aPaintContext.mLayer);
AutoSetOperator setOperator(aPaintContext.mTarget, op);
PaintWithMask(aPaintContext.mTarget,
aPaintContext.mLayer->GetEffectiveOpacity(),
aPaintContext.mLayer->GetMaskLayer());
}
}
/**
* Install the clip applied to the layer on the given gfxContext. The
* given gfxContext is the buffer that the layer will be painted to.
*/
static void InstallLayerClipPreserves3D(gfxContext* aTarget, Layer* aLayer) {
const Maybe<ParentLayerIntRect>& clipRect = aLayer->GetLocalClipRect();
if (!clipRect) {
return;
}
MOZ_ASSERT(
!aLayer->Extend3DContext() || !aLayer->Combines3DTransformWithAncestors(),
"Layers in a preserve 3D context have no clip"
" except leaves and the estabisher!");
Layer* parent = aLayer->GetParent();
Matrix4x4 transform3d = parent && parent->Extend3DContext()
? parent->GetEffectiveTransform()
: Matrix4x4();
Matrix transform;
if (!transform3d.CanDraw2D(&transform)) {
gfxDevCrash(LogReason::CannotDraw3D)
<< "GFX: We should not have a 3D transform that CanDraw2D() is false!";
}
Matrix oldTransform = aTarget->CurrentMatrix();
transform *= oldTransform;
aTarget->SetMatrix(transform);
aTarget->SnappedClip(gfxRect(clipRect->X(), clipRect->Y(), clipRect->Width(),
clipRect->Height()));
aTarget->SetMatrix(oldTransform);
}
void BasicLayerManager::PaintLayer(gfxContext* aTarget, Layer* aLayer,
DrawPaintedLayerCallback aCallback,
void* aCallbackData) {
MOZ_ASSERT(aTarget);
AUTO_PROFILER_LABEL("BasicLayerManager::PaintLayer", GRAPHICS);
PaintLayerContext paintLayerContext(aTarget, aLayer, aCallback,
aCallbackData);
// Don't attempt to paint layers with a singular transform, cairo will
// just throw an error.
if (aLayer->GetEffectiveTransform().IsSingular()) {
return;
}
RenderTraceScope trace("BasicLayerManager::PaintLayer", "707070");
const Maybe<ParentLayerIntRect>& clipRect = aLayer->GetLocalClipRect();
BasicContainerLayer* container =
static_cast<BasicContainerLayer*>(aLayer->AsContainerLayer());
bool needsGroup = container && container->UseIntermediateSurface();
BasicImplData* data = ToData(aLayer);
bool needsClipToVisibleRegion =
data->GetClipToVisibleRegion() && !aLayer->AsPaintedLayer();
NS_ASSERTION(needsGroup || !container ||
container->GetOperator() == CompositionOp::OP_OVER,
"non-OVER operator should have forced UseIntermediateSurface");
NS_ASSERTION(
!container || !aLayer->GetMaskLayer() ||
container->UseIntermediateSurface(),
"ContainerLayer with mask layer should force UseIntermediateSurface");
gfxContextAutoSaveRestore contextSR;
gfxMatrix transform;
// Will return an identity matrix for 3d transforms, and is handled separately
// below.
bool is2D = paintLayerContext.Setup2DTransform();
MOZ_ASSERT(is2D || needsGroup || !container || container->Extend3DContext() ||
container->Is3DContextLeaf(),
"Must PushGroup for 3d transforms!");
Layer* parent = aLayer->GetParent();
bool inPreserves3DChain = parent && parent->Extend3DContext();
bool needsSaveRestore = needsGroup || clipRect || needsClipToVisibleRegion ||
!is2D || inPreserves3DChain;
if (needsSaveRestore) {
contextSR.SetContext(aTarget);
// The clips on ancestors on the preserved3d chain should be
// installed on the aTarget before painting the layer.
InstallLayerClipPreserves3D(aTarget, aLayer);
for (Layer* l = parent; l && l->Extend3DContext(); l = l->GetParent()) {
InstallLayerClipPreserves3D(aTarget, l);
}
}
paintLayerContext.Apply2DTransform();
nsIntRegion visibleRegion = aLayer->GetLocalVisibleRegion().ToUnknownRegion();
// If needsGroup is true, we'll clip to the visible region after we've popped
// the group
if (needsClipToVisibleRegion && !needsGroup) {
gfxUtils::ClipToRegion(aTarget, visibleRegion);
// Don't need to clip to visible region again
needsClipToVisibleRegion = false;
}
if (is2D) {
paintLayerContext.AnnotateOpaqueRect();
}
bool clipIsEmpty = aTarget->GetClipExtents().IsEmpty();
if (clipIsEmpty) {
PaintSelfOrChildren(paintLayerContext, aTarget);
return;
}
if (is2D) {
if (needsGroup) {
PushedGroup pushedGroup;
if (PushGroupForLayer(aTarget, aLayer,
aLayer->GetLocalVisibleRegion().ToUnknownRegion(),
pushedGroup)) {
PaintSelfOrChildren(paintLayerContext, pushedGroup.mGroupTarget);
PopGroupForLayer(pushedGroup);
}
} else {
PaintSelfOrChildren(paintLayerContext, aTarget);
}
} else {
if (!needsGroup && container) {
PaintSelfOrChildren(paintLayerContext, aTarget);
return;
}
IntRect bounds = visibleRegion.GetBounds();
// DrawTarget without the 3D transform applied:
RefPtr<DrawTarget> untransformedDT =
gfxPlatform::GetPlatform()->CreateOffscreenContentDrawTarget(
IntSize(bounds.Width(), bounds.Height()), SurfaceFormat::B8G8R8A8);
if (!untransformedDT || !untransformedDT->IsValid()) {
return;
}
untransformedDT->SetTransform(
Matrix::Translation(-Point(bounds.X(), bounds.Y())));
RefPtr<gfxContext> groupTarget =
gfxContext::CreatePreservingTransformOrNull(untransformedDT);
MOZ_ASSERT(groupTarget); // already checked the target above
PaintSelfOrChildren(paintLayerContext, groupTarget);
// Temporary fast fix for bug 725886
// Revert these changes when 725886 is ready
#ifdef DEBUG
if (aLayer->GetDebugColorIndex() != 0) {
DeviceColor color((aLayer->GetDebugColorIndex() & 1) ? 1.f : 0.f,
(aLayer->GetDebugColorIndex() & 2) ? 1.f : 0.f,
(aLayer->GetDebugColorIndex() & 4) ? 1.f : 0.f);
untransformedDT->FillRect(Rect(bounds), ColorPattern(color));
}
#endif
Matrix4x4 effectiveTransform = aLayer->GetEffectiveTransform();
Rect xformBounds = effectiveTransform.TransformAndClipBounds(
Rect(bounds), ToRect(aTarget->GetClipExtents()));
xformBounds.RoundOut();
effectiveTransform.PostTranslate(-xformBounds.X(), -xformBounds.Y(), 0);
effectiveTransform.PreTranslate(bounds.X(), bounds.Y(), 0);
RefPtr<SourceSurface> untransformedSurf = untransformedDT->Snapshot();
RefPtr<DrawTarget> xformDT = untransformedDT->CreateSimilarDrawTarget(
IntSize::Truncate(xformBounds.Width(), xformBounds.Height()),
SurfaceFormat::B8G8R8A8);
RefPtr<SourceSurface> xformSurf;
if (xformDT && untransformedSurf &&
xformDT->Draw3DTransformedSurface(untransformedSurf,
effectiveTransform)) {
xformSurf = xformDT->Snapshot();
}
if (xformSurf) {
aTarget->SetPattern(new gfxPattern(
xformSurf, Matrix::Translation(xformBounds.TopLeft())));
// Azure doesn't support EXTEND_NONE, so to avoid extending the edges
// of the source surface out to the current clip region, clip to
// the rectangle of the result surface now.
aTarget->SnappedClip(ThebesRect(xformBounds));
FlushGroup(paintLayerContext, needsClipToVisibleRegion);
}
}
}
void BasicLayerManager::ClearCachedResources(Layer* aSubtree) {
MOZ_ASSERT(!aSubtree || aSubtree->Manager() == this);
if (aSubtree) {
ClearLayer(aSubtree);
} else if (mRoot) {
ClearLayer(mRoot);
}
}
void BasicLayerManager::ClearLayer(Layer* aLayer) {
ToData(aLayer)->ClearCachedResources();
for (Layer* child = aLayer->GetFirstChild(); child;
child = child->GetNextSibling()) {
ClearLayer(child);
}
}
already_AddRefed<ReadbackLayer> BasicLayerManager::CreateReadbackLayer() {
NS_ASSERTION(InConstruction(), "Only allowed in construction phase");
RefPtr<ReadbackLayer> layer = new BasicReadbackLayer(this);
return layer.forget();
}
} // namespace layers
} // namespace mozilla

Просмотреть файл

@ -1,243 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef GFX_BASICLAYERS_H
#define GFX_BASICLAYERS_H
#include <stdint.h> // for INT32_MAX, int32_t
#include "gfxTypes.h"
#include "gfxContext.h" // for gfxContext
#include "mozilla/Attributes.h" // for override
#include "mozilla/WidgetUtils.h" // for ScreenRotation
#include "mozilla/layers/LayerManager.h" // for LayerManager::DrawPaintedLayerCallback, LayerManager::END_DEFAULT, LayerManager::EndTra...
#include "mozilla/layers/LayersTypes.h" // for BufferMode, LayersBackend, etc
#include "mozilla/TimeStamp.h"
#include "nsAString.h"
#include "nsCOMPtr.h" // for already_AddRefed
#include "nsISupportsImpl.h" // for gfxContext::AddRef, etc
#include "nsRegion.h" // for nsIntRegion
#include "nscore.h" // for nsAString, etc
class nsIWidget;
namespace mozilla {
namespace layers {
class CanvasLayer;
class ColorLayer;
class ContainerLayer;
class ImageFactory;
class ImageLayer;
class Layer;
class PaintLayerContext;
class PaintedLayer;
class ReadbackLayer;
/**
* This is a cairo/Thebes-only, main-thread-only implementation of layers.
*
* In each transaction, the client sets up the layer tree and then during
* the drawing phase, each PaintedLayer is painted directly into the target
* context (with appropriate clipping and Push/PopGroups performed
* between layers).
*/
class BasicLayerManager final : public LayerManager {
public:
enum BasicLayerManagerType { BLM_WIDGET, BLM_OFFSCREEN, BLM_INACTIVE };
/**
* Construct a BasicLayerManager which will have no default
* target context. SetDefaultTarget or BeginTransactionWithTarget
* must be called for any rendering to happen. PaintedLayers will not
* be retained.
*/
explicit BasicLayerManager(BasicLayerManagerType aType);
/**
* Construct a BasicLayerManager which will have no default
* target context. SetDefaultTarget or BeginTransactionWithTarget
* must be called for any rendering to happen. PaintedLayers will be
* retained; that is, we will try to retain the visible contents of
* PaintedLayers as cairo surfaces. We create PaintedLayer buffers by
* creating similar surfaces to the default target context, or to
* aWidget's GetThebesSurface if there is no default target context, or
* to the passed-in context if there is no widget and no default
* target context.
*
* This does not keep a strong reference to the widget, so the caller
* must ensure that the widget outlives the layer manager or call
* ClearWidget before the widget dies.
*/
explicit BasicLayerManager(nsIWidget* aWidget);
protected:
virtual ~BasicLayerManager();
public:
BasicLayerManager* AsBasicLayerManager() override { return this; }
/**
* Set the default target context that will be used when BeginTransaction
* is called. This can only be called outside a transaction.
*
* aDoubleBuffering can request double-buffering for drawing to the
* default target. When BUFFERED, the layer manager avoids blitting
* temporary results to aContext and then overpainting them with final
* results, by using a temporary buffer when necessary. In BUFFERED
* mode we always completely overwrite the contents of aContext's
* destination surface (within the clip region) using OP_SOURCE.
*/
void SetDefaultTarget(gfxContext* aContext);
virtual void SetDefaultTargetConfiguration(BufferMode aDoubleBuffering,
ScreenRotation aRotation);
gfxContext* GetDefaultTarget() { return mDefaultTarget; }
nsIWidget* GetRetainerWidget() { return mWidget; }
void ClearRetainerWidget() { mWidget = nullptr; }
virtual bool IsWidgetLayerManager() override { return mWidget != nullptr; }
virtual bool IsInactiveLayerManager() override {
return mType == BLM_INACTIVE;
}
virtual bool BeginTransaction(const nsCString& aURL = nsCString()) override;
virtual bool BeginTransactionWithTarget(
gfxContext* aTarget, const nsCString& aURL = nsCString()) override;
virtual bool EndEmptyTransaction(
EndTransactionFlags aFlags = END_DEFAULT) override;
virtual void EndTransaction(
DrawPaintedLayerCallback aCallback, void* aCallbackData,
EndTransactionFlags aFlags = END_DEFAULT) override;
void AbortTransaction();
virtual void SetRoot(Layer* aLayer) override;
virtual already_AddRefed<PaintedLayer> CreatePaintedLayer() override;
virtual already_AddRefed<ContainerLayer> CreateContainerLayer() override;
virtual already_AddRefed<ImageLayer> CreateImageLayer() override;
virtual already_AddRefed<CanvasLayer> CreateCanvasLayer() override;
virtual already_AddRefed<ColorLayer> CreateColorLayer() override;
virtual already_AddRefed<ReadbackLayer> CreateReadbackLayer() override;
virtual ImageFactory* GetImageFactory();
virtual LayersBackend GetBackendType() override {
return LayersBackend::LAYERS_BASIC;
}
virtual void GetBackendName(nsAString& name) override {
name.AssignLiteral("Basic");
}
bool InConstruction() { return mPhase == PHASE_CONSTRUCTION; }
#ifdef DEBUG
bool InDrawing() { return mPhase == PHASE_DRAWING; }
bool InForward() { return mPhase == PHASE_FORWARD; }
#endif
bool InTransaction() { return mPhase != PHASE_NONE; }
gfxContext* GetTarget() { return mTarget; }
void SetTarget(gfxContext* aTarget) {
mUsingDefaultTarget = false;
mTarget = aTarget;
}
bool IsRetained() { return mWidget != nullptr; }
virtual const char* Name() const override { return "Basic"; }
// Clear the cached contents of this layer tree.
virtual void ClearCachedResources(Layer* aSubtree = nullptr) override;
void SetTransactionIncomplete() { mTransactionIncomplete = true; }
bool IsTransactionIncomplete() { return mTransactionIncomplete; }
struct PushedGroup {
PushedGroup()
: mFinalTarget(nullptr),
mNeedsClipToVisibleRegion(false),
mOperator(gfx::CompositionOp::OP_COUNT),
mOpacity(0.0f) {}
gfxContext* mFinalTarget;
RefPtr<gfxContext> mGroupTarget;
nsIntRegion mVisibleRegion;
bool mNeedsClipToVisibleRegion;
gfx::IntPoint mGroupOffset;
gfx::CompositionOp mOperator;
gfx::Float mOpacity;
RefPtr<gfx::SourceSurface> mMaskSurface;
gfx::Matrix mMaskTransform;
};
// Construct a PushedGroup for a specific layer.
// Return false if it has some errors in PushGroupForLayer(). Then, the
// "aGroupResult" is unavailable for future using.
bool PushGroupForLayer(gfxContext* aContext, Layer* aLayerContext,
const nsIntRegion& aRegion, PushedGroup& aGroupResult);
void PopGroupForLayer(PushedGroup& aGroup);
virtual bool IsCompositingCheap() override { return false; }
virtual int32_t GetMaxTextureSize() const override { return INT32_MAX; }
bool CompositorMightResample() { return mCompositorMightResample; }
TimeStamp GetCompositionTime() const { return mCompositionTime; }
protected:
enum TransactionPhase {
PHASE_NONE,
PHASE_CONSTRUCTION,
PHASE_DRAWING,
PHASE_FORWARD
};
TransactionPhase mPhase;
// This is the main body of the PaintLayer routine which will if it has
// children, recurse into PaintLayer() otherwise it will paint using the
// underlying Paint() method of the Layer. It will not do both.
void PaintSelfOrChildren(PaintLayerContext& aPaintContext,
gfxContext* aGroupTarget);
// Paint the group onto the underlying target. This is used by PaintLayer to
// flush the group to the underlying target.
void FlushGroup(PaintLayerContext& aPaintContext,
bool aNeedsClipToVisibleRegion);
// Paints aLayer to mTarget.
void PaintLayer(gfxContext* aTarget, Layer* aLayer,
DrawPaintedLayerCallback aCallback, void* aCallbackData);
// Clear the contents of a layer
void ClearLayer(Layer* aLayer);
bool EndTransactionInternal(DrawPaintedLayerCallback aCallback,
void* aCallbackData,
EndTransactionFlags aFlags = END_DEFAULT);
void FlashWidgetUpdateArea(gfxContext* aContext);
void SetCompositionTime(TimeStamp aTimeStamp) {
mCompositionTime = aTimeStamp;
}
// Widget whose surface should be used as the basis for PaintedLayer
// buffers.
nsIWidget* mWidget;
// The default context for BeginTransaction.
RefPtr<gfxContext> mDefaultTarget;
// The context to draw into.
RefPtr<gfxContext> mTarget;
// Image factory we use.
RefPtr<ImageFactory> mFactory;
BufferMode mDoubleBuffering;
BasicLayerManagerType mType;
bool mUsingDefaultTarget;
bool mTransactionIncomplete;
bool mCompositorMightResample;
TimeStamp mCompositionTime;
};
} // namespace layers
} // namespace mozilla
#endif /* GFX_BASICLAYERS_H */

Просмотреть файл

@ -8,7 +8,6 @@
#define GFX_BASICLAYERSIMPL_H
#include "BasicImplData.h" // for BasicImplData
#include "BasicLayers.h" // for BasicLayerManager
#include "ReadbackLayer.h" // for ReadbackLayer
#include "gfxContext.h" // for gfxContext, etc
#include "mozilla/Attributes.h" // for MOZ_STACK_CLASS
@ -47,29 +46,6 @@ class AutoSetOperator {
RefPtr<gfxContext> mContext;
};
class BasicReadbackLayer : public ReadbackLayer, public BasicImplData {
public:
explicit BasicReadbackLayer(BasicLayerManager* aLayerManager)
: ReadbackLayer(aLayerManager, static_cast<BasicImplData*>(this)) {
MOZ_COUNT_CTOR(BasicReadbackLayer);
}
protected:
MOZ_COUNTED_DTOR_OVERRIDE(BasicReadbackLayer)
public:
void SetVisibleRegion(const LayerIntRegion& aRegion) override {
NS_ASSERTION(BasicManager()->InConstruction(),
"Can only set properties in construction phase");
ReadbackLayer::SetVisibleRegion(aRegion);
}
protected:
BasicLayerManager* BasicManager() {
return static_cast<BasicLayerManager*>(mManager);
}
};
/*
* Extract a mask surface for a mask layer
* Returns true and through outparams a surface for the mask layer if

Просмотреть файл

@ -1,239 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "BasicPaintedLayer.h"
#include <stdint.h> // for uint32_t
#include "ReadbackLayer.h" // for ReadbackLayer, ReadbackSink
#include "ReadbackProcessor.h" // for ReadbackProcessor::Update, etc
#include "RenderTrace.h" // for RenderTraceInvalidateEnd, etc
#include "BasicLayersImpl.h" // for AutoMaskData, etc
#include "gfxContext.h" // for gfxContext, etc
#include "gfxRect.h" // for gfxRect
#include "gfxUtils.h" // for gfxUtils
#include "mozilla/gfx/2D.h" // for DrawTarget
#include "mozilla/gfx/BaseRect.h" // for BaseRect
#include "mozilla/gfx/Matrix.h" // for Matrix
#include "mozilla/gfx/Rect.h" // for Rect, IntRect
#include "mozilla/gfx/Types.h" // for Float, etc
#include "mozilla/layers/LayersTypes.h"
#include "mozilla/ProfilerLabels.h"
#include "nsCOMPtr.h" // for already_AddRefed
#include "nsISupportsImpl.h" // for gfxContext::Release, etc
#include "nsPoint.h" // for nsIntPoint
#include "nsRect.h" // for mozilla::gfx::IntRect
#include "nsTArray.h" // for nsTArray, nsTArray_Impl
#include "AutoMaskData.h"
#include "gfx2DGlue.h"
namespace mozilla {
namespace layers {
using namespace mozilla::gfx;
static nsIntRegion IntersectWithClip(const nsIntRegion& aRegion,
gfxContext* aContext) {
gfxRect clip = aContext->GetClipExtents();
nsIntRegion result;
result.And(aRegion, IntRect::RoundOut(clip.X(), clip.Y(), clip.Width(),
clip.Height()));
return result;
}
void BasicPaintedLayer::PaintThebes(
gfxContext* aContext, Layer* aMaskLayer,
LayerManager::DrawPaintedLayerCallback aCallback, void* aCallbackData) {
AUTO_PROFILER_LABEL("BasicPaintedLayer::PaintThebes", GRAPHICS);
NS_ASSERTION(BasicManager()->InDrawing(), "Can only draw in drawing phase");
float opacity = GetEffectiveOpacity();
CompositionOp effectiveOperator = GetEffectiveOperator(this);
if (!BasicManager()->IsRetained()) {
ClearValidRegion();
mContentClient->Clear();
nsIntRegion toDraw =
IntersectWithClip(GetLocalVisibleRegion().ToUnknownRegion(), aContext);
RenderTraceInvalidateStart(this, "FFFF00", toDraw.GetBounds());
if (!toDraw.IsEmpty() && !IsHidden()) {
if (!aCallback) {
BasicManager()->SetTransactionIncomplete();
return;
}
aContext->Save();
bool needsGroup = opacity != 1.0 ||
effectiveOperator != CompositionOp::OP_OVER ||
aMaskLayer;
RefPtr<gfxContext> context = nullptr;
BasicLayerManager::PushedGroup group;
bool availableGroup = false;
if (needsGroup) {
availableGroup =
BasicManager()->PushGroupForLayer(aContext, this, toDraw, group);
if (availableGroup) {
context = group.mGroupTarget;
}
} else {
context = aContext;
}
if (context) {
DrawTarget* target = context->GetDrawTarget();
bool oldAA = target->GetPermitSubpixelAA();
SetAntialiasingFlags(this, target);
aCallback(this, context, toDraw, toDraw, DrawRegionClip::NONE,
nsIntRegion(), aCallbackData);
target->SetPermitSubpixelAA(oldAA);
}
if (needsGroup && availableGroup) {
BasicManager()->PopGroupForLayer(group);
}
aContext->Restore();
}
RenderTraceInvalidateEnd(this, "FFFF00");
return;
}
if (BasicManager()->IsTransactionIncomplete()) return;
gfxRect clipExtents;
clipExtents = aContext->GetClipExtents();
// Pull out the mask surface and transform here, because the mask
// is internal to basic layers
AutoMoz2DMaskData mask;
SourceSurface* maskSurface = nullptr;
Matrix maskTransform;
if (GetMaskData(aMaskLayer, aContext->GetDeviceOffset(), &mask)) {
maskSurface = mask.GetSurface();
maskTransform = mask.GetTransform();
}
if (!IsHidden() && !clipExtents.IsEmpty()) {
mContentClient->DrawTo(this, aContext->GetDrawTarget(), opacity,
effectiveOperator, maskSurface, &maskTransform);
}
}
void BasicPaintedLayer::Validate(
LayerManager::DrawPaintedLayerCallback aCallback, void* aCallbackData,
ReadbackProcessor* aReadback) {
if (!mContentClient) {
// This client will have a null Forwarder, which means it will not have
// a ContentHost on the other side.
mContentClient = new ContentClientBasic(mBackend);
}
if (!BasicManager()->IsRetained()) {
return;
}
nsTArray<ReadbackProcessor::Update> readbackUpdates;
if (aReadback && UsedForReadback()) {
aReadback->GetPaintedLayerUpdates(this, &readbackUpdates);
}
uint32_t flags = 0;
#ifndef MOZ_WIDGET_ANDROID
if (BasicManager()->CompositorMightResample()) {
flags |= ContentClient::PAINT_WILL_RESAMPLE;
}
if (!(flags & ContentClient::PAINT_WILL_RESAMPLE)) {
if (MayResample()) {
flags |= ContentClient::PAINT_WILL_RESAMPLE;
}
}
#endif
if (mDrawAtomically) {
flags |= ContentClient::PAINT_NO_ROTATION;
}
PaintState state = mContentClient->BeginPaint(this, flags);
SubtractFromValidRegion(state.mRegionToInvalidate);
DrawTarget* target = mContentClient->BorrowDrawTargetForPainting(state);
if (target && target->IsValid()) {
// 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,
GetLocalVisibleRegion().ToUnknownRegion());
SetAntialiasingFlags(this, target);
RenderTraceInvalidateStart(this, "FFFF00", state.mRegionToDraw.GetBounds());
RefPtr<gfxContext> ctx =
gfxContext::CreatePreservingTransformOrNull(target);
MOZ_ASSERT(ctx); // already checked the target above
PaintBuffer(ctx, state.mRegionToDraw, state.mRegionToDraw,
state.mRegionToInvalidate, state.mClip, aCallback,
aCallbackData);
MOZ_LAYERS_LOG_IF_SHADOWABLE(this,
("Layer::Mutated(%p) PaintThebes", this));
Mutated();
ctx = nullptr;
mContentClient->ReturnDrawTarget(target);
target = nullptr;
RenderTraceInvalidateEnd(this, "FFFF00");
} else {
if (target) {
mContentClient->ReturnDrawTarget(target);
target = nullptr;
}
// It's possible that state.mRegionToInvalidate is nonempty here,
// if we are shrinking the valid region to nothing. So use mRegionToDraw
// instead.
NS_WARNING_ASSERTION(
state.mRegionToDraw.IsEmpty(),
"No context when we have something to draw, resource exhaustion?");
}
for (uint32_t i = 0; i < readbackUpdates.Length(); ++i) {
ReadbackProcessor::Update& update = readbackUpdates[i];
nsIntPoint offset = update.mLayer->GetBackgroundLayerOffset();
RefPtr<DrawTarget> dt = update.mLayer->GetSink()->BeginUpdate(
update.mUpdateRect + offset, update.mSequenceCounter);
if (dt) {
NS_ASSERTION(GetEffectiveOpacity() == 1.0,
"Should only read back opaque layers");
NS_ASSERTION(!GetMaskLayer(),
"Should only read back layers without masks");
dt->SetTransform(dt->GetTransform().PreTranslate(offset.x, offset.y));
mContentClient->DrawTo(this, dt, 1.0, CompositionOp::OP_OVER, nullptr,
nullptr);
update.mLayer->GetSink()->EndUpdate(update.mUpdateRect + offset);
}
}
}
already_AddRefed<PaintedLayer> BasicLayerManager::CreatePaintedLayer() {
NS_ASSERTION(InConstruction(), "Only allowed in construction phase");
BackendType backend = gfxPlatform::GetPlatform()->GetDefaultContentBackend();
if (mDefaultTarget) {
backend = mDefaultTarget->GetDrawTarget()->GetBackendType();
} else if (mType == BLM_WIDGET) {
backend = gfxPlatform::GetPlatform()->GetContentBackendFor(
LayersBackend::LAYERS_BASIC);
}
RefPtr<PaintedLayer> layer = new BasicPaintedLayer(this, backend);
return layer.forget();
}
} // namespace layers
} // namespace mozilla

Просмотреть файл

@ -1,121 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef GFX_BASICPAINTEDLAYER_H
#define GFX_BASICPAINTEDLAYER_H
#include "Layers.h" // for PaintedLayer, LayerManager, etc
#include "RotatedBuffer.h" // for RotatedBuffer, etc
#include "BasicImplData.h" // for BasicImplData
#include "BasicLayers.h" // for BasicLayerManager
#include "gfxPoint.h" // for gfxPoint
#include "mozilla/RefPtr.h" // for RefPtr
#include "mozilla/gfx/BasePoint.h" // for BasePoint
#include "mozilla/layers/ContentClient.h" // for ContentClientBasic
#include "mozilla/mozalloc.h" // for operator delete
#include "nsDebug.h" // for NS_ASSERTION
#include "nsISupportsImpl.h" // for MOZ_COUNT_CTOR, etc
#include "nsRegion.h" // for nsIntRegion
class gfxContext;
namespace mozilla {
namespace layers {
class ReadbackProcessor;
class BasicPaintedLayer : public PaintedLayer, public BasicImplData {
public:
typedef ContentClient::PaintState PaintState;
typedef ContentClient::ContentType ContentType;
BasicPaintedLayer(BasicLayerManager* aLayerManager, gfx::BackendType aBackend)
: PaintedLayer(aLayerManager, static_cast<BasicImplData*>(this)),
mContentClient(nullptr),
mBackend(aBackend) {
MOZ_COUNT_CTOR(BasicPaintedLayer);
}
protected:
MOZ_COUNTED_DTOR_OVERRIDE(BasicPaintedLayer)
public:
void SetVisibleRegion(const LayerIntRegion& aRegion) override {
NS_ASSERTION(BasicManager()->InConstruction(),
"Can only set properties in construction phase");
PaintedLayer::SetVisibleRegion(aRegion);
}
void InvalidateRegion(const nsIntRegion& aRegion) override {
NS_ASSERTION(BasicManager()->InConstruction(),
"Can only set properties in construction phase");
mInvalidRegion.Add(aRegion);
UpdateValidRegionAfterInvalidRegionChanged();
}
void PaintThebes(gfxContext* aContext, Layer* aMaskLayer,
LayerManager::DrawPaintedLayerCallback aCallback,
void* aCallbackData) override;
void Validate(LayerManager::DrawPaintedLayerCallback aCallback,
void* aCallbackData, ReadbackProcessor* aReadback) override;
void ClearCachedResources() override {
if (mContentClient) {
mContentClient->Clear();
}
ClearValidRegion();
}
void ComputeEffectiveTransforms(
const gfx::Matrix4x4& aTransformToSurface) override {
if (!BasicManager()->IsRetained()) {
// Don't do any snapping of our transform, since we're just going to
// draw straight through without intermediate buffers.
mEffectiveTransform = GetLocalTransform() * aTransformToSurface;
if (gfxPoint(0, 0) != mResidualTranslation) {
mResidualTranslation = gfxPoint(0, 0);
ClearValidRegion();
}
ComputeEffectiveTransformForMaskLayers(aTransformToSurface);
return;
}
PaintedLayer::ComputeEffectiveTransforms(aTransformToSurface);
}
BasicLayerManager* BasicManager() {
return static_cast<BasicLayerManager*>(mManager);
}
protected:
virtual void PaintBuffer(gfxContext* aContext,
const nsIntRegion& aRegionToDraw,
const nsIntRegion& aExtendedRegionToDraw,
const nsIntRegion& aRegionToInvalidate,
DrawRegionClip aClip,
LayerManager::DrawPaintedLayerCallback aCallback,
void* aCallbackData) {
if (!aCallback) {
BasicManager()->SetTransactionIncomplete();
return;
}
aCallback(this, aContext, aExtendedRegionToDraw, aExtendedRegionToDraw,
aClip, aRegionToInvalidate, aCallbackData);
// Everything that's visible has been validated. Do this instead of just
// OR-ing with aRegionToDraw, since that can lead to a very complex region
// here (OR doesn't automatically simplify to the simplest possible
// representation of a region.)
nsIntRegion tmp;
tmp.Or(mVisibleRegion.ToUnknownRegion(), aExtendedRegionToDraw);
AddToValidRegion(tmp);
}
RefPtr<ContentClientBasic> mContentClient;
gfx::BackendType mBackend;
};
} // namespace layers
} // namespace mozilla
#endif

Просмотреть файл

@ -5,7 +5,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/layers/ContentClient.h"
#include "BasicLayers.h" // for BasicLayerManager
#include "gfxContext.h" // for gfxContext, etc
#include "gfxPlatform.h" // for gfxPlatform
#include "gfxEnv.h" // for gfxEnv
@ -447,59 +446,6 @@ void ContentClient::PrintInfo(std::stringstream& aStream, const char* aPrefix) {
aStream << nsPrintfCString("ContentClient (0x%p)", this).get();
}
// We pass a null pointer for the ContentClient Forwarder argument, which means
// this client will not have a ContentHost on the other side.
ContentClientBasic::ContentClientBasic(gfx::BackendType aBackend)
: ContentClient(nullptr, ContainsVisibleBounds), mBackend(aBackend) {}
void ContentClientBasic::DrawTo(PaintedLayer* aLayer, gfx::DrawTarget* aTarget,
float aOpacity, gfx::CompositionOp aOp,
gfx::SourceSurface* aMask,
const gfx::Matrix* aMaskTransform) {
if (!mBuffer) {
return;
}
mBuffer->DrawTo(aLayer, aTarget, aOpacity, aOp, aMask, aMaskTransform);
}
RefPtr<RotatedBuffer> ContentClientBasic::CreateBuffer(gfxContentType aType,
const IntRect& aRect,
uint32_t aFlags) {
MOZ_ASSERT(!(aFlags & BUFFER_COMPONENT_ALPHA));
if (aFlags & BUFFER_COMPONENT_ALPHA) {
gfxDevCrash(LogReason::AlphaWithBasicClient)
<< "Asking basic content client for component alpha";
}
IntSize size(aRect.Width(), aRect.Height());
RefPtr<gfx::DrawTarget> drawTarget;
#ifdef XP_WIN
if (mBackend == BackendType::CAIRO &&
(aType == gfxContentType::COLOR ||
aType == gfxContentType::COLOR_ALPHA)) {
RefPtr<gfxASurface> surf = new gfxWindowsSurface(
size, aType == gfxContentType::COLOR ? gfxImageFormat::X8R8G8B8_UINT32
: gfxImageFormat::A8R8G8B8_UINT32);
drawTarget = gfxPlatform::CreateDrawTargetForSurface(surf, size);
}
#endif
if (!drawTarget) {
drawTarget = gfxPlatform::GetPlatform()->CreateDrawTargetForBackend(
mBackend, size,
gfxPlatform::GetPlatform()->Optimal2DFormatForContent(aType));
}
if (!drawTarget) {
return nullptr;
}
return new DrawTargetRotatedBuffer(drawTarget, nullptr, aRect,
IntPoint(0, 0));
}
class RemoteBufferReadbackProcessor : public TextureReadbackSink {
public:
RemoteBufferReadbackProcessor(

Просмотреть файл

@ -210,28 +210,6 @@ class ContentClient : public CompositableClient {
BufferSizePolicy mBufferSizePolicy;
};
// Thin wrapper around DrawTargetRotatedBuffer, for on-mtc
class ContentClientBasic final : public ContentClient {
public:
explicit ContentClientBasic(gfx::BackendType aBackend);
void DrawTo(PaintedLayer* aLayer, gfx::DrawTarget* aTarget, float aOpacity,
gfx::CompositionOp aOp, gfx::SourceSurface* aMask,
const gfx::Matrix* aMaskTransform);
TextureInfo GetTextureInfo() const override {
MOZ_CRASH("GFX: Should not be called on non-remote ContentClient");
}
protected:
RefPtr<RotatedBuffer> CreateBuffer(gfxContentType aType,
const gfx::IntRect& aRect,
uint32_t aFlags) override;
private:
gfx::BackendType mBackend;
};
/**
* A ContentClient backed by a RemoteRotatedBuffer.
*

Просмотреть файл

@ -7,8 +7,8 @@
#include "mozilla/layers/CompositorBridgeChild.h"
#include "mozilla/layers/CompositorBridgeParent.h"
#include "mozilla/layers/CompositorThread.h"
#include <stddef.h> // for size_t
#include "base/task.h" // for NewRunnableMethod, etc
#include <stddef.h> // for size_t
#include "base/task.h" // for NewRunnableMethod, etc
#include "mozilla/StaticPrefs_layers.h"
#include "mozilla/layers/CompositorManagerChild.h"
#include "mozilla/layers/ImageBridgeChild.h"

Просмотреть файл

@ -11,11 +11,6 @@ with Files("apz/**"):
BUG_COMPONENT = ("Core", "Panning and Zooming")
EXPORTS += [
"basic/BasicCanvasLayer.h",
"basic/BasicImplData.h",
"basic/BasicLayers.h",
"basic/BasicLayersImpl.h",
"basic/BasicPaintedLayer.h",
"composite/CompositableHost.h",
"composite/ImageHost.h",
"CompositorTypes.h",
@ -386,13 +381,7 @@ UNIFIED_SOURCES += [
"apz/util/TouchCounter.cpp",
"AxisPhysicsModel.cpp",
"AxisPhysicsMSDModel.cpp",
"basic/BasicCanvasLayer.cpp",
"basic/BasicColorLayer.cpp",
"basic/BasicContainerLayer.cpp",
"basic/BasicImages.cpp",
"basic/BasicLayerManager.cpp",
"basic/BasicLayersImpl.cpp",
"basic/BasicPaintedLayer.cpp",
"basic/TextureHostBasic.cpp",
"BSPTree.cpp",
"BufferTexture.cpp",
@ -523,7 +512,6 @@ UNIFIED_SOURCES += [
SOURCES += [
"basic/BasicCompositor.cpp",
"basic/BasicImageLayer.cpp",
"client/TextureClient.cpp",
"ImageContainer.cpp",
"PersistentBufferProvider.cpp",

Просмотреть файл

@ -6,7 +6,6 @@
#include "WebRenderCommandBuilder.h"
#include "BasicLayers.h"
#include "Layers.h"
#include "mozilla/AutoRestore.h"
#include "mozilla/DebugOnly.h"

Просмотреть файл

@ -6,7 +6,6 @@
#include "WebRenderLayerManager.h"
#include "BasicLayers.h"
#include "Layers.h"
#include "GeckoProfiler.h"

Просмотреть файл

@ -6,10 +6,10 @@
#include "WebRenderUserData.h"
#include "BasicLayers.h"
#include "mozilla/layers/AnimationHelper.h"
#include "mozilla/layers/CompositorBridgeChild.h"
#include "mozilla/layers/ImageClient.h"
#include "mozilla/layers/LayerManager.h"
#include "mozilla/layers/WebRenderBridgeChild.h"
#include "mozilla/layers/RenderRootStateManager.h"
#include "mozilla/layers/WebRenderMessages.h"

Просмотреть файл

@ -4,7 +4,7 @@
#include "gtest/gtest.h"
#include "BasicLayers.h"
#include "WindowRenderer.h"
#include "Common.h"
#include "imgIContainer.h"
#include "ImageFactory.h"
@ -52,12 +52,11 @@ TEST_F(ImageContainers, RasterImageContainer) {
RefPtr<ProgressTracker> tracker = image->GetProgressTracker();
tracker->SyncNotifyProgress(FLAG_LOAD_COMPLETE);
RefPtr<layers::LayerManager> layerManager =
new layers::BasicLayerManager(layers::BasicLayerManager::BLM_OFFSCREEN);
RefPtr<WindowRenderer> renderer = new FallbackRenderer;
// Get at native size.
RefPtr<layers::ImageContainer> nativeContainer =
image->GetImageContainer(layerManager, imgIContainer::FLAG_SYNC_DECODE);
image->GetImageContainer(renderer, imgIContainer::FLAG_SYNC_DECODE);
ASSERT_TRUE(nativeContainer != nullptr);
IntSize containerSize = nativeContainer->GetCurrentSize();
EXPECT_EQ(testCase.mSize.width, containerSize.width);
@ -69,7 +68,7 @@ TEST_F(ImageContainers, RasterImageContainer) {
requestedSize.Scale(2, 2);
RefPtr<layers::ImageContainer> upscaleContainer;
drawResult = image->GetImageContainerAtSize(
layerManager, requestedSize, Nothing(), Nothing(),
renderer, requestedSize, Nothing(), Nothing(),
imgIContainer::FLAG_SYNC_DECODE |
imgIContainer::FLAG_HIGH_QUALITY_SCALING,
getter_AddRefs(upscaleContainer));
@ -85,7 +84,7 @@ TEST_F(ImageContainers, RasterImageContainer) {
requestedSize.height /= 2;
RefPtr<layers::ImageContainer> downscaleContainer;
drawResult = image->GetImageContainerAtSize(
layerManager, requestedSize, Nothing(), Nothing(),
renderer, requestedSize, Nothing(), Nothing(),
imgIContainer::FLAG_SYNC_DECODE |
imgIContainer::FLAG_HIGH_QUALITY_SCALING,
getter_AddRefs(downscaleContainer));
@ -98,7 +97,7 @@ TEST_F(ImageContainers, RasterImageContainer) {
// Get at native size again. Should give same container.
RefPtr<layers::ImageContainer> againContainer;
drawResult = image->GetImageContainerAtSize(
layerManager, testCase.mSize, Nothing(), Nothing(),
renderer, testCase.mSize, Nothing(), Nothing(),
imgIContainer::FLAG_SYNC_DECODE, getter_AddRefs(againContainer));
EXPECT_EQ(drawResult, ImgDrawResult::SUCCESS);
ASSERT_EQ(nativeContainer.get(), againContainer.get());

Просмотреть файл

@ -16,7 +16,6 @@
#include "mozilla/layers/WebRenderBridgeChild.h"
#include "mozilla/layers/WebRenderCanvasRenderer.h"
#include "mozilla/layers/RenderRootStateManager.h"
#include "BasicLayers.h"
#include "mozilla/webgpu/CanvasContext.h"
#include "nsDisplayList.h"
#include "nsLayoutUtils.h"

Просмотреть файл

@ -46,7 +46,6 @@
#include "nsObjectLoadingContent.h"
#include "Layers.h"
#include "BasicLayers.h"
#include "mozilla/layers/WebRenderUserData.h"
#include "mozilla/layers/WebRenderScrollData.h"
#include "mozilla/layers/RenderRootStateManager.h"

Просмотреть файл

@ -16,7 +16,6 @@
#include "mozilla/dom/HTMLVideoElement.h"
#include "mozilla/dom/ShadowRoot.h"
#include "mozilla/layers/RenderRootStateManager.h"
#include "BasicLayers.h"
#include "nsDisplayList.h"
#include "nsGenericHTMLElement.h"
#include "nsPresContext.h"

Просмотреть файл

@ -10,9 +10,10 @@
#include "mozilla/layers/LayersTypes.h"
#include "mozilla/dom/Animation.h" // for Animation
#include "mozilla/layers/ScrollableLayerGuid.h" // for ScrollableLayerGuid, ScrollableLayerGuid::ViewID
#include "nsRefPtrHashtable.h" // for nsRefPtrHashtable
#include "mozilla/ScrollPositionUpdate.h" // for ScrollPositionUpdate
#include "nsRefPtrHashtable.h" // for nsRefPtrHashtable
#include "gfxContext.h"
class gfxContext;
namespace mozilla {
namespace layers {
class LayerManager;

Просмотреть файл

@ -54,7 +54,6 @@
#include "mozilla/MathAlgorithms.h"
#include "imgIContainer.h"
#include "BasicLayers.h"
#include "nsBoxFrame.h"
#include "nsImageFrame.h"
#include "nsSubDocumentFrame.h"

Просмотреть файл

@ -17,7 +17,6 @@
#include "nsLayoutUtils.h"
#include "gfxContext.h"
#include "SVGPaintServerFrame.h"
#include "BasicLayers.h"
#include "mozilla/gfx/Point.h"
#include "mozilla/gfx/gfxVars.h"
#include "mozilla/CSSClipPathInstance.h"

Просмотреть файл

@ -25,7 +25,6 @@
#include "mozilla/TextEventDispatcher.h"
#include "mozilla/TextEvents.h"
#include "mozilla/Unused.h"
#include "BasicLayers.h"
#include "PuppetWidget.h"
#include "nsContentUtils.h"
#include "nsIWidgetListener.h"

Просмотреть файл

@ -6,7 +6,6 @@
#include "ErrorList.h"
#include "HeadlessCompositorWidget.h"
#include "Layers.h"
#include "BasicLayers.h"
#include "BasicEvents.h"
#include "MouseEvents.h"
#include "mozilla/gfx/gfxVars.h"

Просмотреть файл

@ -9,7 +9,6 @@
#include <utility>
#include "BasicLayers.h"
#include "GLConsts.h"
#include "InputData.h"
#include "LiveResizeListener.h"
@ -433,13 +432,6 @@ void nsBaseWidget::FreeLocalesChangedObserver() {
nsBaseWidget::~nsBaseWidget() {
IMEStateManager::WidgetDestroyed(this);
if (mWindowRenderer && mWindowRenderer->AsLayerManager()) {
if (BasicLayerManager* mgr =
mWindowRenderer->AsLayerManager()->AsBasicLayerManager()) {
mgr->ClearRetainerWidget();
}
}
FreeLocalesChangedObserver();
FreeShutdownObserver();
RevokeTransactionIdAllocator();
@ -885,28 +877,10 @@ nsBaseWidget::AutoLayerManagerSetup::AutoLayerManagerSetup(
if (renderer->AsFallback()) {
mRenderer = renderer->AsFallback();
mRenderer->SetTarget(aTarget, aDoubleBuffering);
return;
}
LayerManager* lm = renderer ? renderer->AsLayerManager() : nullptr;
NS_ASSERTION(
!lm || lm->GetBackendType() == LayersBackend::LAYERS_BASIC,
"AutoLayerManagerSetup instantiated for non-basic layer backend!");
if (lm) {
mLayerManager = lm->AsBasicLayerManager();
if (mLayerManager) {
mLayerManager->SetDefaultTarget(aTarget);
mLayerManager->SetDefaultTargetConfiguration(aDoubleBuffering,
ROTATION_0);
}
}
}
nsBaseWidget::AutoLayerManagerSetup::~AutoLayerManagerSetup() {
if (mLayerManager) {
mLayerManager->SetDefaultTarget(nullptr);
mLayerManager->SetDefaultTargetConfiguration(
mozilla::layers::BufferMode::BUFFER_NONE, ROTATION_0);
}
if (mRenderer) {
mRenderer->SetTarget(nullptr, mozilla::layers::BufferMode::BUFFER_NONE);
}

Просмотреть файл

@ -57,7 +57,6 @@ class SourceSurface;
} // namespace gfx
namespace layers {
class BasicLayerManager;
class CompositorBridgeChild;
class CompositorBridgeParent;
class IAPZCTreeManager;
@ -143,7 +142,6 @@ class nsBaseWidget : public nsIWidget, public nsSupportsWeakReference {
typedef base::Thread Thread;
typedef mozilla::gfx::DrawTarget DrawTarget;
typedef mozilla::gfx::SourceSurface SourceSurface;
typedef mozilla::layers::BasicLayerManager BasicLayerManager;
typedef mozilla::layers::BufferMode BufferMode;
typedef mozilla::layers::CompositorBridgeChild CompositorBridgeChild;
typedef mozilla::layers::CompositorBridgeParent CompositorBridgeParent;
@ -404,7 +402,6 @@ class nsBaseWidget : public nsIWidget, public nsSupportsWeakReference {
private:
nsBaseWidget* mWidget;
RefPtr<BasicLayerManager> mLayerManager;
mozilla::FallbackRenderer* mRenderer = nullptr;
};
friend class AutoLayerManagerSetup;