mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 867474 - Split BasicShadowableLayerManager into a separate ClientLayerManager. r=nrc
--HG-- rename : gfx/layers/basic/BasicCanvasLayer.cpp => gfx/layers/CopyableCanvasLayer.cpp rename : gfx/layers/basic/BasicCanvasLayer.h => gfx/layers/CopyableCanvasLayer.h rename : gfx/layers/basic/BasicCanvasLayer.cpp => gfx/layers/client/ClientCanvasLayer.cpp rename : gfx/layers/basic/BasicCanvasLayer.h => gfx/layers/client/ClientCanvasLayer.h rename : gfx/layers/basic/BasicColorLayer.cpp => gfx/layers/client/ClientColorLayer.cpp rename : gfx/layers/basic/BasicContainerLayer.cpp => gfx/layers/client/ClientContainerLayer.cpp rename : gfx/layers/basic/BasicContainerLayer.h => gfx/layers/client/ClientContainerLayer.h rename : gfx/layers/basic/BasicImageLayer.cpp => gfx/layers/client/ClientImageLayer.cpp rename : gfx/layers/basic/BasicLayerManager.cpp => gfx/layers/client/ClientLayerManager.cpp rename : gfx/layers/basic/BasicLayers.h => gfx/layers/client/ClientLayerManager.h rename : gfx/layers/basic/BasicThebesLayer.cpp => gfx/layers/client/ClientThebesLayer.cpp rename : gfx/layers/basic/BasicThebesLayer.h => gfx/layers/client/ClientThebesLayer.h rename : gfx/layers/basic/BasicTiledThebesLayer.cpp => gfx/layers/client/ClientTiledThebesLayer.cpp rename : gfx/layers/basic/BasicTiledThebesLayer.h => gfx/layers/client/ClientTiledThebesLayer.h
This commit is contained in:
parent
7fb5e2a39b
commit
c727739057
220
gfx/layers/CopyableCanvasLayer.cpp
Normal file
220
gfx/layers/CopyableCanvasLayer.cpp
Normal file
@ -0,0 +1,220 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* 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 "mozilla/layers/PLayerTransactionParent.h"
|
||||
#include "CopyableCanvasLayer.h"
|
||||
#include "BasicLayersImpl.h"
|
||||
#include "gfxImageSurface.h"
|
||||
#include "GLContext.h"
|
||||
#include "gfxUtils.h"
|
||||
#include "gfxPlatform.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "SurfaceStream.h"
|
||||
#include "SharedSurfaceGL.h"
|
||||
#include "SharedSurfaceEGL.h"
|
||||
#include "GeckoProfiler.h"
|
||||
|
||||
#include "nsXULAppAPI.h"
|
||||
|
||||
using namespace mozilla::gfx;
|
||||
using namespace mozilla::gl;
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
void
|
||||
CopyableCanvasLayer::Initialize(const Data& aData)
|
||||
{
|
||||
NS_ASSERTION(mSurface == nullptr, "BasicCanvasLayer::Initialize called twice!");
|
||||
|
||||
if (aData.mSurface) {
|
||||
mSurface = aData.mSurface;
|
||||
NS_ASSERTION(!aData.mGLContext, "CanvasLayer can't have both surface and GLContext");
|
||||
mNeedsYFlip = false;
|
||||
} else if (aData.mGLContext) {
|
||||
mGLContext = aData.mGLContext;
|
||||
mIsGLAlphaPremult = aData.mIsGLAlphaPremult;
|
||||
mNeedsYFlip = true;
|
||||
MOZ_ASSERT(mGLContext->IsOffscreen(), "canvas gl context isn't offscreen");
|
||||
|
||||
// [Basic Layers, non-OMTC] WebGL layer init.
|
||||
// `GLScreenBuffer::Morph`ing is only needed in BasicShadowableCanvasLayer.
|
||||
} else if (aData.mDrawTarget) {
|
||||
mDrawTarget = aData.mDrawTarget;
|
||||
mSurface = gfxPlatform::GetPlatform()->GetThebesSurfaceForDrawTarget(mDrawTarget);
|
||||
mNeedsYFlip = false;
|
||||
} else {
|
||||
NS_ERROR("CanvasLayer created without mSurface, mDrawTarget or mGLContext?");
|
||||
}
|
||||
|
||||
mBounds.SetRect(0, 0, aData.mSize.width, aData.mSize.height);
|
||||
}
|
||||
|
||||
void
|
||||
CopyableCanvasLayer::UpdateSurface(gfxASurface* aDestSurface, Layer* aMaskLayer)
|
||||
{
|
||||
if (!IsDirty())
|
||||
return;
|
||||
Painted();
|
||||
|
||||
if (mDrawTarget) {
|
||||
mDrawTarget->Flush();
|
||||
if (mDrawTarget->GetType() == BACKEND_COREGRAPHICS_ACCELERATED) {
|
||||
// We have an accelerated CG context which has changed, unlike a bitmap surface
|
||||
// where we can alias the bits on initializing the mDrawTarget, we need to readback
|
||||
// and copy the accelerated surface each frame. We want to support this for quick
|
||||
// thumbnail but if we're going to be doing this every frame it likely is better
|
||||
// to use a non accelerated (bitmap) canvas.
|
||||
mSurface = gfxPlatform::GetPlatform()->GetThebesSurfaceForDrawTarget(mDrawTarget);
|
||||
}
|
||||
}
|
||||
|
||||
if (!mGLContext && aDestSurface) {
|
||||
nsRefPtr<gfxContext> tmpCtx = new gfxContext(aDestSurface);
|
||||
tmpCtx->SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||
CopyableCanvasLayer::PaintWithOpacity(tmpCtx, 1.0f, aMaskLayer);
|
||||
return;
|
||||
}
|
||||
|
||||
if (mGLContext) {
|
||||
if (aDestSurface && aDestSurface->GetType() != gfxASurface::SurfaceTypeImage) {
|
||||
MOZ_ASSERT(false, "Destination surface must be ImageSurface type.");
|
||||
return;
|
||||
}
|
||||
|
||||
nsRefPtr<gfxImageSurface> readSurf;
|
||||
nsRefPtr<gfxImageSurface> resultSurf;
|
||||
|
||||
SharedSurface* sharedSurf = mGLContext->RequestFrame();
|
||||
if (!sharedSurf) {
|
||||
NS_WARNING("Null frame received.");
|
||||
return;
|
||||
}
|
||||
|
||||
gfxIntSize readSize(sharedSurf->Size());
|
||||
gfxImageFormat format = (GetContentFlags() & CONTENT_OPAQUE)
|
||||
? gfxASurface::ImageFormatRGB24
|
||||
: gfxASurface::ImageFormatARGB32;
|
||||
|
||||
if (aDestSurface) {
|
||||
resultSurf = static_cast<gfxImageSurface*>(aDestSurface);
|
||||
} else {
|
||||
resultSurf = GetTempSurface(readSize, format);
|
||||
}
|
||||
MOZ_ASSERT(resultSurf);
|
||||
if (resultSurf->CairoStatus() != 0) {
|
||||
MOZ_ASSERT(false, "Bad resultSurf->CairoStatus().");
|
||||
return;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(sharedSurf->APIType() == APITypeT::OpenGL);
|
||||
SharedSurface_GL* surfGL = SharedSurface_GL::Cast(sharedSurf);
|
||||
|
||||
if (surfGL->Type() == SharedSurfaceType::Basic) {
|
||||
SharedSurface_Basic* sharedSurf_Basic = SharedSurface_Basic::Cast(surfGL);
|
||||
readSurf = sharedSurf_Basic->GetData();
|
||||
} else {
|
||||
if (resultSurf->Format() == format &&
|
||||
resultSurf->GetSize() == readSize)
|
||||
{
|
||||
readSurf = resultSurf;
|
||||
} else {
|
||||
readSurf = GetTempSurface(readSize, format);
|
||||
}
|
||||
|
||||
// Readback handles Flush/MarkDirty.
|
||||
mGLContext->Screen()->Readback(surfGL, readSurf);
|
||||
}
|
||||
MOZ_ASSERT(readSurf);
|
||||
|
||||
bool needsPremult = surfGL->HasAlpha() && !mIsGLAlphaPremult;
|
||||
if (needsPremult) {
|
||||
gfxImageSurface* sizedReadSurf = nullptr;
|
||||
if (readSurf->Format() == resultSurf->Format() &&
|
||||
readSurf->GetSize() == resultSurf->GetSize())
|
||||
{
|
||||
sizedReadSurf = readSurf;
|
||||
} else {
|
||||
readSurf->Flush();
|
||||
nsRefPtr<gfxContext> ctx = new gfxContext(resultSurf);
|
||||
ctx->SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||
ctx->SetSource(readSurf);
|
||||
ctx->Paint();
|
||||
|
||||
sizedReadSurf = resultSurf;
|
||||
}
|
||||
MOZ_ASSERT(sizedReadSurf);
|
||||
|
||||
readSurf->Flush();
|
||||
resultSurf->Flush();
|
||||
gfxUtils::PremultiplyImageSurface(readSurf, resultSurf);
|
||||
resultSurf->MarkDirty();
|
||||
} else if (resultSurf != readSurf) {
|
||||
// Didn't need premult, but we do need to blit to resultSurf
|
||||
readSurf->Flush();
|
||||
nsRefPtr<gfxContext> ctx = new gfxContext(resultSurf);
|
||||
ctx->SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||
ctx->SetSource(readSurf);
|
||||
ctx->Paint();
|
||||
}
|
||||
|
||||
// stick our surface into mSurface, so that the Paint() path is the same
|
||||
if (!aDestSurface) {
|
||||
mSurface = resultSurf;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CopyableCanvasLayer::PaintWithOpacity(gfxContext* aContext,
|
||||
float aOpacity,
|
||||
Layer* aMaskLayer,
|
||||
gfxContext::GraphicsOperator aOperator)
|
||||
{
|
||||
if (!mSurface) {
|
||||
NS_WARNING("No valid surface to draw!");
|
||||
return;
|
||||
}
|
||||
|
||||
nsRefPtr<gfxPattern> pat = new gfxPattern(mSurface);
|
||||
|
||||
pat->SetFilter(mFilter);
|
||||
pat->SetExtend(gfxPattern::EXTEND_PAD);
|
||||
|
||||
gfxMatrix m;
|
||||
if (mNeedsYFlip) {
|
||||
m = aContext->CurrentMatrix();
|
||||
aContext->Translate(gfxPoint(0.0, mBounds.height));
|
||||
aContext->Scale(1.0, -1.0);
|
||||
}
|
||||
|
||||
// If content opaque, then save off current operator and set to source.
|
||||
// This ensures that alpha is not applied even if the source surface
|
||||
// has an alpha channel
|
||||
gfxContext::GraphicsOperator savedOp;
|
||||
if (GetContentFlags() & CONTENT_OPAQUE) {
|
||||
savedOp = aContext->CurrentOperator();
|
||||
aContext->SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||
}
|
||||
|
||||
AutoSetOperator setOperator(aContext, aOperator);
|
||||
aContext->NewPath();
|
||||
// No need to snap here; our transform is already set up to snap our rect
|
||||
aContext->Rectangle(gfxRect(0, 0, mBounds.width, mBounds.height));
|
||||
aContext->SetPattern(pat);
|
||||
|
||||
FillWithMask(aContext, aOpacity, aMaskLayer);
|
||||
// Restore surface operator
|
||||
if (GetContentFlags() & CONTENT_OPAQUE) {
|
||||
aContext->SetOperator(savedOp);
|
||||
}
|
||||
|
||||
if (mNeedsYFlip) {
|
||||
aContext->SetMatrix(m);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
91
gfx/layers/CopyableCanvasLayer.h
Normal file
91
gfx/layers/CopyableCanvasLayer.h
Normal file
@ -0,0 +1,91 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* 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_COPYABLECANVASLAYER_H
|
||||
#define GFX_COPYABLECANVASLAYER_H
|
||||
|
||||
#include "Layers.h"
|
||||
#include "mozilla/layers/CanvasClient.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
|
||||
#include "gfxPlatform.h"
|
||||
|
||||
using namespace mozilla::gfx;
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
class CanvasClient2D;
|
||||
class CanvasClientWebGL;
|
||||
|
||||
/**
|
||||
* A shared CanvasLayer implementation that supports copying
|
||||
* its contents into a gfxASurface using UpdateSurface.
|
||||
*/
|
||||
class CopyableCanvasLayer : public CanvasLayer
|
||||
{
|
||||
public:
|
||||
CopyableCanvasLayer(LayerManager* aLayerManager, void *aImplData) :
|
||||
CanvasLayer(aLayerManager, aImplData)
|
||||
{
|
||||
MOZ_COUNT_CTOR(CopyableCanvasLayer);
|
||||
mForceReadback = Preferences::GetBool("webgl.force-layers-readback", false);
|
||||
}
|
||||
virtual ~CopyableCanvasLayer()
|
||||
{
|
||||
MOZ_COUNT_DTOR(CopyableCanvasLayer);
|
||||
}
|
||||
|
||||
virtual void Initialize(const Data& aData);
|
||||
|
||||
|
||||
protected:
|
||||
void PaintWithOpacity(gfxContext* aContext,
|
||||
float aOpacity,
|
||||
Layer* aMaskLayer,
|
||||
gfxContext::GraphicsOperator aOperator = gfxContext::OPERATOR_OVER);
|
||||
|
||||
void UpdateSurface(gfxASurface* aDestSurface = nullptr, Layer* aMaskLayer = nullptr);
|
||||
|
||||
nsRefPtr<gfxASurface> mSurface;
|
||||
nsRefPtr<mozilla::gl::GLContext> mGLContext;
|
||||
mozilla::RefPtr<mozilla::gfx::DrawTarget> mDrawTarget;
|
||||
|
||||
uint32_t mCanvasFramebuffer;
|
||||
|
||||
bool mIsGLAlphaPremult;
|
||||
bool mNeedsYFlip;
|
||||
bool mForceReadback;
|
||||
|
||||
nsRefPtr<gfxImageSurface> mCachedTempSurface;
|
||||
gfxIntSize mCachedSize;
|
||||
gfxImageFormat mCachedFormat;
|
||||
|
||||
gfxImageSurface* GetTempSurface(const gfxIntSize& aSize, const gfxImageFormat aFormat)
|
||||
{
|
||||
if (!mCachedTempSurface ||
|
||||
aSize.width != mCachedSize.width ||
|
||||
aSize.height != mCachedSize.height ||
|
||||
aFormat != mCachedFormat)
|
||||
{
|
||||
mCachedTempSurface = new gfxImageSurface(aSize, aFormat);
|
||||
mCachedSize = aSize;
|
||||
mCachedFormat = aFormat;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(mCachedTempSurface->Stride() == mCachedTempSurface->Width() * 4);
|
||||
return mCachedTempSurface;
|
||||
}
|
||||
|
||||
void DiscardTempSurface()
|
||||
{
|
||||
mCachedTempSurface = nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -37,6 +37,7 @@ enum LayersBackend {
|
||||
LAYERS_OPENGL,
|
||||
LAYERS_D3D9,
|
||||
LAYERS_D3D10,
|
||||
LAYERS_CLIENT,
|
||||
LAYERS_LAST
|
||||
};
|
||||
|
||||
|
@ -38,9 +38,16 @@ CPPSRCS = \
|
||||
BasicImageLayer.cpp \
|
||||
BasicLayersImpl.cpp \
|
||||
BasicThebesLayer.cpp \
|
||||
BasicTiledThebesLayer.cpp \
|
||||
ClientCanvasLayer.cpp \
|
||||
ClientColorLayer.cpp \
|
||||
ClientContainerLayer.cpp \
|
||||
ClientImageLayer.cpp \
|
||||
ClientLayerManager.cpp \
|
||||
ClientThebesLayer.cpp \
|
||||
ClientTiledThebesLayer.cpp \
|
||||
CompositableHost.cpp \
|
||||
CompositableTransactionParent.cpp \
|
||||
CopyableCanvasLayer.cpp \
|
||||
ImageContainer.cpp \
|
||||
Layers.cpp \
|
||||
LayersLogging.cpp \
|
||||
|
@ -24,149 +24,6 @@ using namespace mozilla::gl;
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
void
|
||||
BasicCanvasLayer::Initialize(const Data& aData)
|
||||
{
|
||||
NS_ASSERTION(mSurface == nullptr, "BasicCanvasLayer::Initialize called twice!");
|
||||
|
||||
if (aData.mSurface) {
|
||||
mSurface = aData.mSurface;
|
||||
NS_ASSERTION(!aData.mGLContext, "CanvasLayer can't have both surface and GLContext");
|
||||
mNeedsYFlip = false;
|
||||
} else if (aData.mGLContext) {
|
||||
mGLContext = aData.mGLContext;
|
||||
mIsGLAlphaPremult = aData.mIsGLAlphaPremult;
|
||||
mNeedsYFlip = true;
|
||||
MOZ_ASSERT(mGLContext->IsOffscreen(), "canvas gl context isn't offscreen");
|
||||
|
||||
// [Basic Layers, non-OMTC] WebGL layer init.
|
||||
// `GLScreenBuffer::Morph`ing is only needed in BasicShadowableCanvasLayer.
|
||||
} else if (aData.mDrawTarget) {
|
||||
mDrawTarget = aData.mDrawTarget;
|
||||
mSurface = gfxPlatform::GetPlatform()->GetThebesSurfaceForDrawTarget(mDrawTarget);
|
||||
mNeedsYFlip = false;
|
||||
} else {
|
||||
NS_ERROR("CanvasLayer created without mSurface, mDrawTarget or mGLContext?");
|
||||
}
|
||||
|
||||
mBounds.SetRect(0, 0, aData.mSize.width, aData.mSize.height);
|
||||
}
|
||||
|
||||
void
|
||||
BasicCanvasLayer::UpdateSurface(gfxASurface* aDestSurface, Layer* aMaskLayer)
|
||||
{
|
||||
if (!IsDirty())
|
||||
return;
|
||||
Painted();
|
||||
|
||||
if (mDrawTarget) {
|
||||
mDrawTarget->Flush();
|
||||
if (mDrawTarget->GetType() == BACKEND_COREGRAPHICS_ACCELERATED) {
|
||||
// We have an accelerated CG context which has changed, unlike a bitmap surface
|
||||
// where we can alias the bits on initializing the mDrawTarget, we need to readback
|
||||
// and copy the accelerated surface each frame. We want to support this for quick
|
||||
// thumbnail but if we're going to be doing this every frame it likely is better
|
||||
// to use a non accelerated (bitmap) canvas.
|
||||
mSurface = gfxPlatform::GetPlatform()->GetThebesSurfaceForDrawTarget(mDrawTarget);
|
||||
}
|
||||
}
|
||||
|
||||
if (!mGLContext && aDestSurface) {
|
||||
nsRefPtr<gfxContext> tmpCtx = new gfxContext(aDestSurface);
|
||||
tmpCtx->SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||
BasicCanvasLayer::PaintWithOpacity(tmpCtx, 1.0f, aMaskLayer);
|
||||
return;
|
||||
}
|
||||
|
||||
if (mGLContext) {
|
||||
if (aDestSurface && aDestSurface->GetType() != gfxASurface::SurfaceTypeImage) {
|
||||
MOZ_ASSERT(false, "Destination surface must be ImageSurface type.");
|
||||
return;
|
||||
}
|
||||
|
||||
nsRefPtr<gfxImageSurface> readSurf;
|
||||
nsRefPtr<gfxImageSurface> resultSurf;
|
||||
|
||||
SharedSurface* sharedSurf = mGLContext->RequestFrame();
|
||||
if (!sharedSurf) {
|
||||
NS_WARNING("Null frame received.");
|
||||
return;
|
||||
}
|
||||
|
||||
gfxIntSize readSize(sharedSurf->Size());
|
||||
gfxImageFormat format = (GetContentFlags() & CONTENT_OPAQUE)
|
||||
? gfxASurface::ImageFormatRGB24
|
||||
: gfxASurface::ImageFormatARGB32;
|
||||
|
||||
if (aDestSurface) {
|
||||
resultSurf = static_cast<gfxImageSurface*>(aDestSurface);
|
||||
} else {
|
||||
resultSurf = GetTempSurface(readSize, format);
|
||||
}
|
||||
MOZ_ASSERT(resultSurf);
|
||||
if (resultSurf->CairoStatus() != 0) {
|
||||
MOZ_ASSERT(false, "Bad resultSurf->CairoStatus().");
|
||||
return;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(sharedSurf->APIType() == APITypeT::OpenGL);
|
||||
SharedSurface_GL* surfGL = SharedSurface_GL::Cast(sharedSurf);
|
||||
|
||||
if (surfGL->Type() == SharedSurfaceType::Basic) {
|
||||
SharedSurface_Basic* sharedSurf_Basic = SharedSurface_Basic::Cast(surfGL);
|
||||
readSurf = sharedSurf_Basic->GetData();
|
||||
} else {
|
||||
if (resultSurf->Format() == format &&
|
||||
resultSurf->GetSize() == readSize)
|
||||
{
|
||||
readSurf = resultSurf;
|
||||
} else {
|
||||
readSurf = GetTempSurface(readSize, format);
|
||||
}
|
||||
|
||||
// Readback handles Flush/MarkDirty.
|
||||
mGLContext->Screen()->Readback(surfGL, readSurf);
|
||||
}
|
||||
MOZ_ASSERT(readSurf);
|
||||
|
||||
bool needsPremult = surfGL->HasAlpha() && !mIsGLAlphaPremult;
|
||||
if (needsPremult) {
|
||||
gfxImageSurface* sizedReadSurf = nullptr;
|
||||
if (readSurf->Format() == resultSurf->Format() &&
|
||||
readSurf->GetSize() == resultSurf->GetSize())
|
||||
{
|
||||
sizedReadSurf = readSurf;
|
||||
} else {
|
||||
readSurf->Flush();
|
||||
nsRefPtr<gfxContext> ctx = new gfxContext(resultSurf);
|
||||
ctx->SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||
ctx->SetSource(readSurf);
|
||||
ctx->Paint();
|
||||
|
||||
sizedReadSurf = resultSurf;
|
||||
}
|
||||
MOZ_ASSERT(sizedReadSurf);
|
||||
|
||||
readSurf->Flush();
|
||||
resultSurf->Flush();
|
||||
gfxUtils::PremultiplyImageSurface(readSurf, resultSurf);
|
||||
resultSurf->MarkDirty();
|
||||
} else if (resultSurf != readSurf) {
|
||||
// Didn't need premult, but we do need to blit to resultSurf
|
||||
readSurf->Flush();
|
||||
nsRefPtr<gfxContext> ctx = new gfxContext(resultSurf);
|
||||
ctx->SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||
ctx->SetSource(readSurf);
|
||||
ctx->Paint();
|
||||
}
|
||||
|
||||
// stick our surface into mSurface, so that the Paint() path is the same
|
||||
if (!aDestSurface) {
|
||||
mSurface = resultSurf;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
BasicCanvasLayer::Paint(gfxContext* aContext, Layer* aMaskLayer)
|
||||
{
|
||||
@ -177,145 +34,9 @@ BasicCanvasLayer::Paint(gfxContext* aContext, Layer* aMaskLayer)
|
||||
UpdateSurface();
|
||||
FireDidTransactionCallback();
|
||||
|
||||
PaintWithOpacity(aContext, GetEffectiveOpacity(), aMaskLayer);
|
||||
PaintWithOpacity(aContext, GetEffectiveOpacity(), aMaskLayer, GetOperator());
|
||||
}
|
||||
|
||||
void
|
||||
BasicCanvasLayer::PaintWithOpacity(gfxContext* aContext,
|
||||
float aOpacity,
|
||||
Layer* aMaskLayer)
|
||||
{
|
||||
NS_ASSERTION(BasicManager()->InDrawing(),
|
||||
"Can only draw in drawing phase");
|
||||
|
||||
if (!mSurface) {
|
||||
NS_WARNING("No valid surface to draw!");
|
||||
return;
|
||||
}
|
||||
|
||||
nsRefPtr<gfxPattern> pat = new gfxPattern(mSurface);
|
||||
|
||||
pat->SetFilter(mFilter);
|
||||
pat->SetExtend(gfxPattern::EXTEND_PAD);
|
||||
|
||||
gfxMatrix m;
|
||||
if (mNeedsYFlip) {
|
||||
m = aContext->CurrentMatrix();
|
||||
aContext->Translate(gfxPoint(0.0, mBounds.height));
|
||||
aContext->Scale(1.0, -1.0);
|
||||
}
|
||||
|
||||
// If content opaque, then save off current operator and set to source.
|
||||
// This ensures that alpha is not applied even if the source surface
|
||||
// has an alpha channel
|
||||
gfxContext::GraphicsOperator savedOp;
|
||||
if (GetContentFlags() & CONTENT_OPAQUE) {
|
||||
savedOp = aContext->CurrentOperator();
|
||||
aContext->SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||
}
|
||||
|
||||
AutoSetOperator setOperator(aContext, GetOperator());
|
||||
aContext->NewPath();
|
||||
// No need to snap here; our transform is already set up to snap our rect
|
||||
aContext->Rectangle(gfxRect(0, 0, mBounds.width, mBounds.height));
|
||||
aContext->SetPattern(pat);
|
||||
|
||||
FillWithMask(aContext, aOpacity, aMaskLayer);
|
||||
// Restore surface operator
|
||||
if (GetContentFlags() & CONTENT_OPAQUE) {
|
||||
aContext->SetOperator(savedOp);
|
||||
}
|
||||
|
||||
if (mNeedsYFlip) {
|
||||
aContext->SetMatrix(m);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
BasicShadowableCanvasLayer::Initialize(const Data& aData)
|
||||
{
|
||||
BasicCanvasLayer::Initialize(aData);
|
||||
if (!HasShadow())
|
||||
return;
|
||||
|
||||
mCanvasClient = nullptr;
|
||||
|
||||
if (mGLContext) {
|
||||
GLScreenBuffer* screen = mGLContext->Screen();
|
||||
SurfaceStreamType streamType =
|
||||
SurfaceStream::ChooseGLStreamType(SurfaceStream::OffMainThread,
|
||||
screen->PreserveBuffer());
|
||||
SurfaceFactory_GL* factory = nullptr;
|
||||
if (!mForceReadback) {
|
||||
if (BasicManager()->GetCompositorBackendType() == mozilla::layers::LAYERS_OPENGL) {
|
||||
if (mGLContext->GetEGLContext()) {
|
||||
bool isCrossProcess = !(XRE_GetProcessType() == GeckoProcessType_Default);
|
||||
|
||||
if (!isCrossProcess) {
|
||||
// [Basic/OGL Layers, OMTC] WebGL layer init.
|
||||
factory = SurfaceFactory_EGLImage::Create(mGLContext, screen->Caps());
|
||||
} else {
|
||||
// [Basic/OGL Layers, OOPC] WebGL layer init. (Out Of Process Compositing)
|
||||
// Fall back to readback.
|
||||
}
|
||||
} else {
|
||||
// [Basic Layers, OMTC] WebGL layer init.
|
||||
// Well, this *should* work...
|
||||
factory = new SurfaceFactory_GLTexture(mGLContext, mGLContext, screen->Caps());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (factory) {
|
||||
screen->Morph(factory, streamType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
BasicShadowableCanvasLayer::Paint(gfxContext* aContext, Layer* aMaskLayer)
|
||||
{
|
||||
PROFILER_LABEL("BasicShadowableCanvasLayer", "Paint");
|
||||
if (!HasShadow()) {
|
||||
BasicCanvasLayer::Paint(aContext, aMaskLayer);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!IsDirty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (aMaskLayer) {
|
||||
static_cast<BasicImplData*>(aMaskLayer->ImplData())
|
||||
->Paint(aContext, nullptr);
|
||||
}
|
||||
|
||||
if (!mCanvasClient) {
|
||||
TextureFlags flags = 0;
|
||||
if (mNeedsYFlip) {
|
||||
flags |= NeedsYFlip;
|
||||
}
|
||||
mCanvasClient = CanvasClient::CreateCanvasClient(GetCompositableClientType(),
|
||||
BasicManager(), flags);
|
||||
if (!mCanvasClient) {
|
||||
return;
|
||||
}
|
||||
if (HasShadow()) {
|
||||
mCanvasClient->Connect();
|
||||
BasicManager()->Attach(mCanvasClient, this);
|
||||
}
|
||||
}
|
||||
|
||||
FirePreTransactionCallback();
|
||||
mCanvasClient->Update(gfx::IntSize(mBounds.width, mBounds.height), this);
|
||||
|
||||
FireDidTransactionCallback();
|
||||
|
||||
BasicManager()->Hold(this);
|
||||
mCanvasClient->Updated();
|
||||
}
|
||||
|
||||
|
||||
already_AddRefed<CanvasLayer>
|
||||
BasicLayerManager::CreateCanvasLayer()
|
||||
{
|
||||
@ -324,16 +45,5 @@ BasicLayerManager::CreateCanvasLayer()
|
||||
return layer.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<CanvasLayer>
|
||||
BasicShadowLayerManager::CreateCanvasLayer()
|
||||
{
|
||||
NS_ASSERTION(InConstruction(), "Only allowed in construction phase");
|
||||
nsRefPtr<BasicShadowableCanvasLayer> layer =
|
||||
new BasicShadowableCanvasLayer(this);
|
||||
MAYBE_CREATE_SHADOW(Canvas);
|
||||
return layer.forget();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "BasicImplData.h"
|
||||
#include "mozilla/layers/CanvasClient.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "CopyableCanvasLayer.h"
|
||||
|
||||
#include "gfxPlatform.h"
|
||||
|
||||
@ -23,137 +24,28 @@ namespace layers {
|
||||
class CanvasClient2D;
|
||||
class CanvasClientWebGL;
|
||||
|
||||
class BasicCanvasLayer : public CanvasLayer,
|
||||
class BasicCanvasLayer : public CopyableCanvasLayer,
|
||||
public BasicImplData
|
||||
{
|
||||
public:
|
||||
BasicCanvasLayer(BasicLayerManager* aLayerManager) :
|
||||
CanvasLayer(aLayerManager, static_cast<BasicImplData*>(this))
|
||||
{
|
||||
MOZ_COUNT_CTOR(BasicCanvasLayer);
|
||||
mForceReadback = Preferences::GetBool("webgl.force-layers-readback", false);
|
||||
}
|
||||
virtual ~BasicCanvasLayer()
|
||||
{
|
||||
MOZ_COUNT_DTOR(BasicCanvasLayer);
|
||||
}
|
||||
|
||||
CopyableCanvasLayer(aLayerManager, static_cast<BasicImplData*>(this))
|
||||
{ }
|
||||
|
||||
virtual void SetVisibleRegion(const nsIntRegion& aRegion)
|
||||
{
|
||||
NS_ASSERTION(BasicManager()->InConstruction(),
|
||||
"Can only set properties in construction phase");
|
||||
CanvasLayer::SetVisibleRegion(aRegion);
|
||||
}
|
||||
|
||||
virtual void Initialize(const Data& aData);
|
||||
|
||||
virtual void Paint(gfxContext* aContext, Layer* aMaskLayer);
|
||||
|
||||
virtual void PaintWithOpacity(gfxContext* aContext,
|
||||
float aOpacity,
|
||||
Layer* aMaskLayer);
|
||||
|
||||
|
||||
protected:
|
||||
BasicLayerManager* BasicManager()
|
||||
{
|
||||
return static_cast<BasicLayerManager*>(mManager);
|
||||
}
|
||||
void UpdateSurface(gfxASurface* aDestSurface = nullptr, Layer* aMaskLayer = nullptr);
|
||||
|
||||
nsRefPtr<gfxASurface> mSurface;
|
||||
nsRefPtr<mozilla::gl::GLContext> mGLContext;
|
||||
mozilla::RefPtr<mozilla::gfx::DrawTarget> mDrawTarget;
|
||||
|
||||
uint32_t mCanvasFramebuffer;
|
||||
|
||||
bool mIsGLAlphaPremult;
|
||||
bool mNeedsYFlip;
|
||||
bool mForceReadback;
|
||||
|
||||
nsRefPtr<gfxImageSurface> mCachedTempSurface;
|
||||
gfxIntSize mCachedSize;
|
||||
gfxImageFormat mCachedFormat;
|
||||
|
||||
gfxImageSurface* GetTempSurface(const gfxIntSize& aSize, const gfxImageFormat aFormat)
|
||||
{
|
||||
if (!mCachedTempSurface ||
|
||||
aSize.width != mCachedSize.width ||
|
||||
aSize.height != mCachedSize.height ||
|
||||
aFormat != mCachedFormat)
|
||||
{
|
||||
mCachedTempSurface = new gfxImageSurface(aSize, aFormat);
|
||||
mCachedSize = aSize;
|
||||
mCachedFormat = aFormat;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(mCachedTempSurface->Stride() == mCachedTempSurface->Width() * 4);
|
||||
return mCachedTempSurface;
|
||||
}
|
||||
|
||||
void DiscardTempSurface()
|
||||
{
|
||||
mCachedTempSurface = nullptr;
|
||||
}
|
||||
|
||||
friend class CanvasClient2D;
|
||||
friend class CanvasClientWebGL;
|
||||
};
|
||||
|
||||
class BasicShadowableCanvasLayer : public BasicCanvasLayer,
|
||||
public BasicShadowableLayer
|
||||
{
|
||||
public:
|
||||
BasicShadowableCanvasLayer(BasicShadowLayerManager* aManager) :
|
||||
BasicCanvasLayer(aManager),
|
||||
mCanvasClient(nullptr)
|
||||
{
|
||||
MOZ_COUNT_CTOR(BasicShadowableCanvasLayer);
|
||||
}
|
||||
virtual ~BasicShadowableCanvasLayer()
|
||||
{
|
||||
MOZ_COUNT_DTOR(BasicShadowableCanvasLayer);
|
||||
}
|
||||
|
||||
virtual void Initialize(const Data& aData);
|
||||
virtual void Paint(gfxContext* aContext, Layer* aMaskLayer);
|
||||
|
||||
virtual void FillSpecificAttributes(SpecificLayerAttributes& aAttrs)
|
||||
{
|
||||
aAttrs = CanvasLayerAttributes(mFilter, mBounds);
|
||||
}
|
||||
|
||||
virtual Layer* AsLayer() { return this; }
|
||||
virtual ShadowableLayer* AsShadowableLayer() { return this; }
|
||||
|
||||
/*virtual void SetBackBuffer(const SurfaceDescriptor& aBuffer)
|
||||
{
|
||||
NS_ERROR("Should not be called.");
|
||||
}*/
|
||||
|
||||
virtual void Disconnect()
|
||||
{
|
||||
mCanvasClient = nullptr;
|
||||
BasicShadowableLayer::Disconnect();
|
||||
}
|
||||
|
||||
virtual CompositableClient* GetCompositableClient() MOZ_OVERRIDE
|
||||
{
|
||||
return mCanvasClient;
|
||||
}
|
||||
private:
|
||||
BasicShadowLayerManager* BasicManager()
|
||||
{
|
||||
return static_cast<BasicShadowLayerManager*>(mManager);
|
||||
}
|
||||
|
||||
CompositableType GetCompositableClientType()
|
||||
{
|
||||
if (mGLContext && XRE_GetProcessType() == GeckoProcessType_Default) {
|
||||
return BUFFER_IMAGE_BUFFERED;
|
||||
}
|
||||
return BUFFER_IMAGE_SINGLE;
|
||||
}
|
||||
|
||||
RefPtr<CanvasClient> mCanvasClient;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -58,52 +58,6 @@ BasicColorLayer::PaintColorTo(gfxRGBA aColor, float aOpacity,
|
||||
PaintWithMask(aContext, aOpacity, aMaskLayer);
|
||||
}
|
||||
|
||||
class BasicShadowableColorLayer : public BasicColorLayer,
|
||||
public BasicShadowableLayer
|
||||
{
|
||||
public:
|
||||
BasicShadowableColorLayer(BasicShadowLayerManager* aManager) :
|
||||
BasicColorLayer(aManager)
|
||||
{
|
||||
MOZ_COUNT_CTOR(BasicShadowableColorLayer);
|
||||
}
|
||||
virtual ~BasicShadowableColorLayer()
|
||||
{
|
||||
MOZ_COUNT_DTOR(BasicShadowableColorLayer);
|
||||
}
|
||||
|
||||
virtual void FillSpecificAttributes(SpecificLayerAttributes& aAttrs)
|
||||
{
|
||||
aAttrs = ColorLayerAttributes(GetColor());
|
||||
}
|
||||
|
||||
virtual Layer* AsLayer() { return this; }
|
||||
virtual ShadowableLayer* AsShadowableLayer() { return this; }
|
||||
|
||||
virtual void Disconnect()
|
||||
{
|
||||
BasicShadowableLayer::Disconnect();
|
||||
}
|
||||
|
||||
virtual void Paint(gfxContext* aContext, Layer* aMaskLayer);
|
||||
};
|
||||
|
||||
void
|
||||
BasicShadowableColorLayer::Paint(gfxContext* aContext, Layer* aMaskLayer)
|
||||
{
|
||||
BasicColorLayer::Paint(aContext, aMaskLayer);
|
||||
|
||||
if (!HasShadow()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (aMaskLayer) {
|
||||
static_cast<BasicImplData*>(aMaskLayer->ImplData())
|
||||
->Paint(aContext, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
already_AddRefed<ColorLayer>
|
||||
BasicLayerManager::CreateColorLayer()
|
||||
{
|
||||
@ -111,15 +65,6 @@ BasicLayerManager::CreateColorLayer()
|
||||
nsRefPtr<ColorLayer> layer = new BasicColorLayer(this);
|
||||
return layer.forget();
|
||||
}
|
||||
already_AddRefed<ColorLayer>
|
||||
BasicShadowLayerManager::CreateColorLayer()
|
||||
{
|
||||
NS_ASSERTION(InConstruction(), "Only allowed in construction phase");
|
||||
nsRefPtr<BasicShadowableColorLayer> layer =
|
||||
new BasicShadowableColorLayer(this);
|
||||
MAYBE_CREATE_SHADOW(Color);
|
||||
return layer.forget();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -59,124 +59,6 @@ BasicContainerLayer::ChildrenPartitionVisibleRegion(const nsIntRect& aInRect)
|
||||
return covered.Contains(rect);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
class BasicShadowableContainerLayer : public BasicContainerLayer,
|
||||
public BasicShadowableLayer {
|
||||
public:
|
||||
BasicShadowableContainerLayer(BasicShadowLayerManager* aManager) :
|
||||
BasicContainerLayer(aManager)
|
||||
{
|
||||
MOZ_COUNT_CTOR(BasicShadowableContainerLayer);
|
||||
}
|
||||
virtual ~BasicShadowableContainerLayer()
|
||||
{
|
||||
MOZ_COUNT_DTOR(BasicShadowableContainerLayer);
|
||||
}
|
||||
|
||||
virtual void InsertAfter(Layer* aChild, Layer* aAfter);
|
||||
virtual void RemoveChild(Layer* aChild);
|
||||
virtual void RepositionChild(Layer* aChild, Layer* aAfter);
|
||||
|
||||
virtual Layer* AsLayer() { return this; }
|
||||
virtual ShadowableLayer* AsShadowableLayer() { return this; }
|
||||
|
||||
virtual void Disconnect()
|
||||
{
|
||||
BasicShadowableLayer::Disconnect();
|
||||
}
|
||||
|
||||
virtual void ComputeEffectiveTransforms(const gfx3DMatrix& aTransformToSurface) MOZ_OVERRIDE
|
||||
{
|
||||
if (HasShadow()) {
|
||||
DefaultComputeEffectiveTransforms(aTransformToSurface);
|
||||
} else {
|
||||
BasicContainerLayer::ComputeEffectiveTransforms(aTransformToSurface);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
BasicShadowLayerManager* ShadowManager()
|
||||
{
|
||||
return static_cast<BasicShadowLayerManager*>(mManager);
|
||||
}
|
||||
};
|
||||
|
||||
void
|
||||
BasicShadowableContainerLayer::InsertAfter(Layer* aChild, Layer* aAfter)
|
||||
{
|
||||
if (HasShadow() && ShouldShadow(aChild)) {
|
||||
while (aAfter && !ShouldShadow(aAfter)) {
|
||||
aAfter = aAfter->GetPrevSibling();
|
||||
}
|
||||
ShadowManager()->InsertAfter(ShadowManager()->Hold(this),
|
||||
ShadowManager()->Hold(aChild),
|
||||
aAfter ? ShadowManager()->Hold(aAfter) : nullptr);
|
||||
}
|
||||
BasicContainerLayer::InsertAfter(aChild, aAfter);
|
||||
}
|
||||
|
||||
void
|
||||
BasicShadowableContainerLayer::RemoveChild(Layer* aChild)
|
||||
{
|
||||
if (HasShadow() && ShouldShadow(aChild)) {
|
||||
ShadowManager()->RemoveChild(ShadowManager()->Hold(this),
|
||||
ShadowManager()->Hold(aChild));
|
||||
}
|
||||
BasicContainerLayer::RemoveChild(aChild);
|
||||
}
|
||||
|
||||
void
|
||||
BasicShadowableContainerLayer::RepositionChild(Layer* aChild, Layer* aAfter)
|
||||
{
|
||||
if (HasShadow() && ShouldShadow(aChild)) {
|
||||
while (aAfter && !ShouldShadow(aAfter)) {
|
||||
aAfter = aAfter->GetPrevSibling();
|
||||
}
|
||||
ShadowManager()->RepositionChild(ShadowManager()->Hold(this),
|
||||
ShadowManager()->Hold(aChild),
|
||||
aAfter ? ShadowManager()->Hold(aAfter) : nullptr);
|
||||
}
|
||||
BasicContainerLayer::RepositionChild(aChild, aAfter);
|
||||
}
|
||||
|
||||
class BasicShadowableRefLayer : public RefLayer, public BasicImplData,
|
||||
public BasicShadowableLayer {
|
||||
template<class Container>
|
||||
friend void ContainerComputeEffectiveTransforms(const gfx3DMatrix& aTransformToSurface,
|
||||
Container* aContainer);
|
||||
public:
|
||||
BasicShadowableRefLayer(BasicShadowLayerManager* aManager) :
|
||||
RefLayer(aManager, static_cast<BasicImplData*>(this))
|
||||
{
|
||||
MOZ_COUNT_CTOR(BasicShadowableRefLayer);
|
||||
}
|
||||
virtual ~BasicShadowableRefLayer()
|
||||
{
|
||||
MOZ_COUNT_DTOR(BasicShadowableRefLayer);
|
||||
}
|
||||
|
||||
virtual Layer* AsLayer() { return this; }
|
||||
virtual ShadowableLayer* AsShadowableLayer() { return this; }
|
||||
|
||||
virtual void Disconnect()
|
||||
{
|
||||
BasicShadowableLayer::Disconnect();
|
||||
}
|
||||
|
||||
virtual void ComputeEffectiveTransforms(const gfx3DMatrix& aTransformToSurface)
|
||||
{
|
||||
ContainerComputeEffectiveTransforms(aTransformToSurface, this);
|
||||
}
|
||||
|
||||
private:
|
||||
BasicShadowLayerManager* ShadowManager()
|
||||
{
|
||||
return static_cast<BasicShadowLayerManager*>(mManager);
|
||||
}
|
||||
};
|
||||
|
||||
already_AddRefed<ContainerLayer>
|
||||
BasicLayerManager::CreateContainerLayer()
|
||||
{
|
||||
@ -185,26 +67,5 @@ BasicLayerManager::CreateContainerLayer()
|
||||
return layer.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<ContainerLayer>
|
||||
BasicShadowLayerManager::CreateContainerLayer()
|
||||
{
|
||||
NS_ASSERTION(InConstruction(), "Only allowed in construction phase");
|
||||
nsRefPtr<BasicShadowableContainerLayer> layer =
|
||||
new BasicShadowableContainerLayer(this);
|
||||
MAYBE_CREATE_SHADOW(Container);
|
||||
return layer.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<RefLayer>
|
||||
BasicShadowLayerManager::CreateRefLayer()
|
||||
{
|
||||
NS_ASSERTION(InConstruction(), "Only allowed in construction phase");
|
||||
nsRefPtr<BasicShadowableRefLayer> layer =
|
||||
new BasicShadowableRefLayer(this);
|
||||
MAYBE_CREATE_SHADOW(Ref);
|
||||
return layer.forget();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -157,130 +157,6 @@ BasicImageLayer::GetAsSurface(gfxASurface** aSurface,
|
||||
return true;
|
||||
}
|
||||
|
||||
class BasicShadowableImageLayer : public BasicImageLayer,
|
||||
public BasicShadowableLayer
|
||||
{
|
||||
public:
|
||||
BasicShadowableImageLayer(BasicShadowLayerManager* aManager) :
|
||||
BasicImageLayer(aManager),
|
||||
mImageClient(nullptr),
|
||||
mImageClientTypeContainer(BUFFER_UNKNOWN)
|
||||
{
|
||||
MOZ_COUNT_CTOR(BasicShadowableImageLayer);
|
||||
}
|
||||
virtual ~BasicShadowableImageLayer()
|
||||
{
|
||||
DestroyBackBuffer();
|
||||
MOZ_COUNT_DTOR(BasicShadowableImageLayer);
|
||||
}
|
||||
|
||||
virtual void SetContainer(ImageContainer* aContainer) MOZ_OVERRIDE
|
||||
{
|
||||
ImageLayer::SetContainer(aContainer);
|
||||
mImageClientTypeContainer = BUFFER_UNKNOWN;
|
||||
}
|
||||
|
||||
virtual void Paint(gfxContext* aContext, Layer* aMaskLayer);
|
||||
|
||||
virtual void ClearCachedResources() MOZ_OVERRIDE
|
||||
{
|
||||
DestroyBackBuffer();
|
||||
}
|
||||
|
||||
virtual void FillSpecificAttributes(SpecificLayerAttributes& aAttrs)
|
||||
{
|
||||
aAttrs = ImageLayerAttributes(mFilter);
|
||||
}
|
||||
|
||||
virtual Layer* AsLayer() { return this; }
|
||||
virtual ShadowableLayer* AsShadowableLayer() { return this; }
|
||||
|
||||
virtual void Disconnect()
|
||||
{
|
||||
DestroyBackBuffer();
|
||||
BasicShadowableLayer::Disconnect();
|
||||
}
|
||||
|
||||
void DestroyBackBuffer()
|
||||
{
|
||||
mImageClient = nullptr;
|
||||
}
|
||||
|
||||
virtual CompositableClient* GetCompositableClient() MOZ_OVERRIDE
|
||||
{
|
||||
return mImageClient;
|
||||
}
|
||||
private:
|
||||
BasicShadowLayerManager* BasicManager()
|
||||
{
|
||||
return static_cast<BasicShadowLayerManager*>(mManager);
|
||||
}
|
||||
|
||||
CompositableType GetImageClientType()
|
||||
{
|
||||
if (mImageClientTypeContainer != BUFFER_UNKNOWN) {
|
||||
return mImageClientTypeContainer;
|
||||
}
|
||||
|
||||
if (mContainer->IsAsync()) {
|
||||
mImageClientTypeContainer = BUFFER_BRIDGE;
|
||||
return mImageClientTypeContainer;
|
||||
}
|
||||
|
||||
nsRefPtr<gfxASurface> surface;
|
||||
AutoLockImage autoLock(mContainer, getter_AddRefs(surface));
|
||||
|
||||
mImageClientTypeContainer = autoLock.GetImage() ?
|
||||
BUFFER_IMAGE_SINGLE : BUFFER_UNKNOWN;
|
||||
return mImageClientTypeContainer;
|
||||
}
|
||||
|
||||
RefPtr<ImageClient> mImageClient;
|
||||
CompositableType mImageClientTypeContainer;
|
||||
};
|
||||
|
||||
void
|
||||
BasicShadowableImageLayer::Paint(gfxContext* aContext, Layer* aMaskLayer)
|
||||
{
|
||||
if (!HasShadow()) {
|
||||
BasicImageLayer::Paint(aContext, aMaskLayer);
|
||||
return;
|
||||
}
|
||||
|
||||
if (aMaskLayer) {
|
||||
static_cast<BasicImplData*>(aMaskLayer->ImplData())
|
||||
->Paint(aContext, nullptr);
|
||||
}
|
||||
|
||||
if (!mContainer) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mImageClient ||
|
||||
!mImageClient->UpdateImage(mContainer, GetContentFlags())) {
|
||||
mImageClient = ImageClient::CreateImageClient(GetImageClientType(),
|
||||
BasicManager(),
|
||||
mForceSingleTile
|
||||
? ForceSingleTile
|
||||
: 0);
|
||||
if (GetImageClientType() == BUFFER_BRIDGE) {
|
||||
static_cast<ImageClientBridge*>(mImageClient.get())->SetLayer(this);
|
||||
}
|
||||
|
||||
if (!mImageClient) {
|
||||
return;
|
||||
}
|
||||
if (HasShadow() && !mContainer->IsAsync()) {
|
||||
mImageClient->Connect();
|
||||
BasicManager()->Attach(mImageClient, this);
|
||||
}
|
||||
if (!mImageClient->UpdateImage(mContainer, GetContentFlags())) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
BasicManager()->Hold(this);
|
||||
}
|
||||
|
||||
already_AddRefed<ImageLayer>
|
||||
BasicLayerManager::CreateImageLayer()
|
||||
{
|
||||
@ -288,15 +164,6 @@ BasicLayerManager::CreateImageLayer()
|
||||
nsRefPtr<ImageLayer> layer = new BasicImageLayer(this);
|
||||
return layer.forget();
|
||||
}
|
||||
already_AddRefed<ImageLayer>
|
||||
BasicShadowLayerManager::CreateImageLayer()
|
||||
{
|
||||
NS_ASSERTION(InConstruction(), "Only allowed in construction phase");
|
||||
nsRefPtr<BasicShadowableImageLayer> layer =
|
||||
new BasicShadowableImageLayer(this);
|
||||
MAYBE_CREATE_SHADOW(Image);
|
||||
return layer.forget();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -20,7 +20,6 @@
|
||||
#define PIXMAN_DONT_DEFINE_STDINT
|
||||
#include "pixman.h"
|
||||
|
||||
#include "BasicTiledThebesLayer.h"
|
||||
#include "BasicLayersImpl.h"
|
||||
#include "BasicThebesLayer.h"
|
||||
#include "BasicContainerLayer.h"
|
||||
@ -873,16 +872,6 @@ BasicLayerManager::FlushGroup(PaintLayerContext& aPaintContext, bool aNeedsClipT
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
HasOpaqueAncestorLayer(Layer* aLayer)
|
||||
{
|
||||
for (Layer* l = aLayer->GetParent(); l; l = l->GetParent()) {
|
||||
if (l->GetContentFlags() & Layer::CONTENT_OPAQUE)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
BasicLayerManager::PaintLayer(gfxContext* aTarget,
|
||||
Layer* aLayer,
|
||||
@ -917,28 +906,6 @@ BasicLayerManager::PaintLayer(gfxContext* aTarget,
|
||||
container->UseIntermediateSurface(),
|
||||
"ContainerLayer with mask layer should force UseIntermediateSurface");
|
||||
|
||||
// If we're a shadowable ContainerLayer, then setup mSupportsComponentAlphaChildren
|
||||
// in the same way that ContainerLayerComposite will do. Otherwise leave it set to
|
||||
// true.
|
||||
ShadowableLayer* shadow = aLayer->AsShadowableLayer();
|
||||
if (aLayer->GetFirstChild() && shadow && shadow->HasShadow()) {
|
||||
if (needsGroup) {
|
||||
if (container->GetEffectiveVisibleRegion().GetNumRects() != 1 ||
|
||||
!(container->GetContentFlags() & Layer::CONTENT_OPAQUE))
|
||||
{
|
||||
const gfx3DMatrix& transform3D = container->GetEffectiveTransform();
|
||||
gfxMatrix transform;
|
||||
if (HasOpaqueAncestorLayer(container) &&
|
||||
transform3D.Is2D(&transform) && !transform.HasNonIntegerTranslation()) {
|
||||
container->SetSupportsComponentAlphaChildren(gfxPlatform::GetPlatform()->UsesSubpixelAATextRendering());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
container->SetSupportsComponentAlphaChildren((container->GetContentFlags() & Layer::CONTENT_OPAQUE) ||
|
||||
(container->GetParent() && container->GetParent()->SupportsComponentAlphaChildren()));
|
||||
}
|
||||
}
|
||||
|
||||
gfxContextAutoSaveRestore contextSR;
|
||||
gfxMatrix transform;
|
||||
// Will return an identity matrix for 3d transforms, and is handled separately below.
|
||||
@ -1066,330 +1033,5 @@ BasicLayerManager::CreateReadbackLayer()
|
||||
return layer.forget();
|
||||
}
|
||||
|
||||
BasicShadowLayerManager::BasicShadowLayerManager(nsIWidget* aWidget) :
|
||||
BasicLayerManager(aWidget), mTargetRotation(ROTATION_0),
|
||||
mRepeatTransaction(false), mIsRepeatTransaction(false)
|
||||
{
|
||||
MOZ_COUNT_CTOR(BasicShadowLayerManager);
|
||||
}
|
||||
|
||||
BasicShadowLayerManager::~BasicShadowLayerManager()
|
||||
{
|
||||
MOZ_COUNT_DTOR(BasicShadowLayerManager);
|
||||
}
|
||||
|
||||
int32_t
|
||||
BasicShadowLayerManager::GetMaxTextureSize() const
|
||||
{
|
||||
if (HasShadowManager()) {
|
||||
return ShadowLayerForwarder::GetMaxTextureSize();
|
||||
}
|
||||
|
||||
return INT32_MAX;
|
||||
}
|
||||
|
||||
void
|
||||
BasicShadowLayerManager::SetDefaultTargetConfiguration(BufferMode aDoubleBuffering, ScreenRotation aRotation)
|
||||
{
|
||||
BasicLayerManager::SetDefaultTargetConfiguration(aDoubleBuffering, aRotation);
|
||||
mTargetRotation = aRotation;
|
||||
if (mWidget) {
|
||||
mTargetBounds = mWidget->GetNaturalBounds();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
BasicShadowLayerManager::SetRoot(Layer* aLayer)
|
||||
{
|
||||
if (mRoot != aLayer) {
|
||||
if (HasShadowManager()) {
|
||||
// Have to hold the old root and its children in order to
|
||||
// maintain the same view of the layer tree in this process as
|
||||
// the parent sees. Otherwise layers can be destroyed
|
||||
// mid-transaction and bad things can happen (v. bug 612573)
|
||||
if (mRoot) {
|
||||
Hold(mRoot);
|
||||
}
|
||||
ShadowLayerForwarder::SetRoot(Hold(aLayer));
|
||||
}
|
||||
BasicLayerManager::SetRoot(aLayer);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
BasicShadowLayerManager::Mutated(Layer* aLayer)
|
||||
{
|
||||
BasicLayerManager::Mutated(aLayer);
|
||||
|
||||
NS_ASSERTION(InConstruction() || InDrawing(), "wrong phase");
|
||||
if (HasShadowManager() && ShouldShadow(aLayer)) {
|
||||
ShadowLayerForwarder::Mutated(Hold(aLayer));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
BasicShadowLayerManager::BeginTransactionWithTarget(gfxContext* aTarget)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(mKeepAlive.IsEmpty(), "uncommitted txn?");
|
||||
nsRefPtr<gfxContext> targetContext = aTarget;
|
||||
|
||||
// If the last transaction was incomplete (a failed DoEmptyTransaction),
|
||||
// don't signal a new transaction to ShadowLayerForwarder. Carry on adding
|
||||
// to the previous transaction.
|
||||
if (HasShadowManager()) {
|
||||
ScreenOrientation orientation;
|
||||
nsIntRect clientBounds;
|
||||
if (TabChild* window = mWidget->GetOwningTabChild()) {
|
||||
orientation = window->GetOrientation();
|
||||
} else {
|
||||
hal::ScreenConfiguration currentConfig;
|
||||
hal::GetCurrentScreenConfiguration(¤tConfig);
|
||||
orientation = currentConfig.orientation();
|
||||
}
|
||||
mWidget->GetClientBounds(clientBounds);
|
||||
ShadowLayerForwarder::BeginTransaction(mTargetBounds, mTargetRotation, clientBounds, orientation);
|
||||
|
||||
// If we're drawing on behalf of a context with async pan/zoom
|
||||
// enabled, then the entire buffer of thebes layers might be
|
||||
// composited (including resampling) asynchronously before we get
|
||||
// a chance to repaint, so we have to ensure that it's all valid
|
||||
// and not rotated.
|
||||
if (mWidget) {
|
||||
if (TabChild* window = mWidget->GetOwningTabChild()) {
|
||||
mCompositorMightResample = window->IsAsyncPanZoomEnabled();
|
||||
}
|
||||
}
|
||||
|
||||
// If we have a non-default target, we need to let our shadow manager draw
|
||||
// to it. This will happen at the end of the transaction.
|
||||
if (aTarget && ((aTarget != mDefaultTarget) || Compositor::GetBackend() == LAYERS_BASIC) &&
|
||||
XRE_GetProcessType() == GeckoProcessType_Default) {
|
||||
mShadowTarget = aTarget;
|
||||
|
||||
gfxASurface::gfxContentType contentType;
|
||||
|
||||
if (aTarget->IsCairo()) {
|
||||
contentType = aTarget->OriginalSurface()->GetContentType();
|
||||
} else {
|
||||
contentType = aTarget->GetDrawTarget()->GetFormat() == FORMAT_B8G8R8X8 ?
|
||||
gfxASurface::CONTENT_COLOR : gfxASurface::CONTENT_COLOR_ALPHA;
|
||||
}
|
||||
// Create a temporary target for ourselves, so that
|
||||
// mShadowTarget is only drawn to for the window snapshot.
|
||||
nsRefPtr<gfxASurface> dummy =
|
||||
gfxPlatform::GetPlatform()->CreateOffscreenSurface(
|
||||
gfxIntSize(1, 1),
|
||||
contentType);
|
||||
mDummyTarget = new gfxContext(dummy);
|
||||
aTarget = mDummyTarget;
|
||||
}
|
||||
}
|
||||
BasicLayerManager::BeginTransactionWithTarget(aTarget);
|
||||
}
|
||||
|
||||
void
|
||||
BasicShadowLayerManager::EndTransaction(DrawThebesLayerCallback aCallback,
|
||||
void* aCallbackData,
|
||||
EndTransactionFlags aFlags)
|
||||
{
|
||||
if (mWidget) {
|
||||
mWidget->PrepareWindowEffects();
|
||||
}
|
||||
BasicLayerManager::EndTransaction(aCallback, aCallbackData, aFlags);
|
||||
ForwardTransaction();
|
||||
|
||||
if (mRepeatTransaction) {
|
||||
mRepeatTransaction = false;
|
||||
mIsRepeatTransaction = true;
|
||||
BasicLayerManager::BeginTransaction();
|
||||
BasicShadowLayerManager::EndTransaction(aCallback, aCallbackData, aFlags);
|
||||
mIsRepeatTransaction = false;
|
||||
} else {
|
||||
MakeSnapshotIfRequired();
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
BasicShadowLayerManager::EndEmptyTransaction(EndTransactionFlags aFlags)
|
||||
{
|
||||
if (!BasicLayerManager::EndEmptyTransaction(aFlags)) {
|
||||
// Return without calling ForwardTransaction. This leaves the
|
||||
// ShadowLayerForwarder transaction open; the following
|
||||
// EndTransaction will complete it.
|
||||
return false;
|
||||
}
|
||||
ForwardTransaction();
|
||||
MakeSnapshotIfRequired();
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
BasicShadowLayerManager::MakeSnapshotIfRequired()
|
||||
{
|
||||
if (!mShadowTarget) {
|
||||
return;
|
||||
}
|
||||
if (mWidget) {
|
||||
if (CompositorChild* remoteRenderer = mWidget->GetRemoteRenderer()) {
|
||||
nsIntRect bounds;
|
||||
mWidget->GetBounds(bounds);
|
||||
SurfaceDescriptor inSnapshot, snapshot;
|
||||
if (AllocSurfaceDescriptor(bounds.Size(),
|
||||
gfxASurface::CONTENT_COLOR_ALPHA,
|
||||
&inSnapshot) &&
|
||||
// The compositor will usually reuse |snapshot| and return
|
||||
// it through |outSnapshot|, but if it doesn't, it's
|
||||
// responsible for freeing |snapshot|.
|
||||
remoteRenderer->SendMakeSnapshot(inSnapshot, &snapshot)) {
|
||||
AutoOpenSurface opener(OPEN_READ_ONLY, snapshot);
|
||||
gfxASurface* source = opener.Get();
|
||||
|
||||
mShadowTarget->DrawSurface(source, source->GetSize());
|
||||
}
|
||||
if (IsSurfaceDescriptorValid(snapshot)) {
|
||||
ShadowLayerForwarder::DestroySharedSurface(&snapshot);
|
||||
}
|
||||
}
|
||||
}
|
||||
mShadowTarget = nullptr;
|
||||
mDummyTarget = nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
BasicShadowLayerManager::ForwardTransaction()
|
||||
{
|
||||
RenderTraceScope rendertrace("Foward Transaction", "000090");
|
||||
mPhase = PHASE_FORWARD;
|
||||
|
||||
// forward this transaction's changeset to our LayerManagerComposite
|
||||
AutoInfallibleTArray<EditReply, 10> replies;
|
||||
if (HasShadowManager() && ShadowLayerForwarder::EndTransaction(&replies)) {
|
||||
for (nsTArray<EditReply>::size_type i = 0; i < replies.Length(); ++i) {
|
||||
const EditReply& reply = replies[i];
|
||||
|
||||
switch (reply.type()) {
|
||||
case EditReply::TOpContentBufferSwap: {
|
||||
MOZ_LAYERS_LOG(("[LayersForwarder] DoubleBufferSwap"));
|
||||
|
||||
const OpContentBufferSwap& obs = reply.get_OpContentBufferSwap();
|
||||
|
||||
CompositableChild* compositableChild =
|
||||
static_cast<CompositableChild*>(obs.compositableChild());
|
||||
ContentClientRemote* contentClient =
|
||||
static_cast<ContentClientRemote*>(compositableChild->GetCompositableClient());
|
||||
MOZ_ASSERT(contentClient);
|
||||
|
||||
contentClient->SwapBuffers(obs.frontUpdatedRegion());
|
||||
|
||||
break;
|
||||
}
|
||||
case EditReply::TOpTextureSwap: {
|
||||
MOZ_LAYERS_LOG(("[LayersForwarder] TextureSwap"));
|
||||
|
||||
const OpTextureSwap& ots = reply.get_OpTextureSwap();
|
||||
|
||||
CompositableChild* compositableChild =
|
||||
static_cast<CompositableChild*>(ots.compositableChild());
|
||||
MOZ_ASSERT(compositableChild);
|
||||
|
||||
compositableChild->GetCompositableClient()
|
||||
->SetDescriptorFromReply(ots.textureId(), ots.image());
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
NS_RUNTIMEABORT("not reached");
|
||||
}
|
||||
}
|
||||
} else if (HasShadowManager()) {
|
||||
NS_WARNING("failed to forward Layers transaction");
|
||||
}
|
||||
|
||||
mPhase = PHASE_NONE;
|
||||
|
||||
// this may result in Layers being deleted, which results in
|
||||
// PLayer::Send__delete__() and DeallocShmem()
|
||||
mKeepAlive.Clear();
|
||||
}
|
||||
|
||||
ShadowableLayer*
|
||||
BasicShadowLayerManager::Hold(Layer* aLayer)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(HasShadowManager(),
|
||||
"top-level tree, no shadow tree to remote to");
|
||||
|
||||
ShadowableLayer* shadowable = ToShadowable(aLayer);
|
||||
NS_ABORT_IF_FALSE(shadowable, "trying to remote an unshadowable layer");
|
||||
|
||||
mKeepAlive.AppendElement(aLayer);
|
||||
return shadowable;
|
||||
}
|
||||
|
||||
bool
|
||||
BasicShadowLayerManager::IsCompositingCheap()
|
||||
{
|
||||
// Whether compositing is cheap depends on the parent backend.
|
||||
return mShadowManager &&
|
||||
LayerManager::IsCompositingCheap(GetCompositorBackendType());
|
||||
}
|
||||
|
||||
void
|
||||
BasicShadowLayerManager::SetIsFirstPaint()
|
||||
{
|
||||
ShadowLayerForwarder::SetIsFirstPaint();
|
||||
}
|
||||
|
||||
void
|
||||
BasicShadowLayerManager::ClearCachedResources(Layer* aSubtree)
|
||||
{
|
||||
MOZ_ASSERT(!HasShadowManager() || !aSubtree);
|
||||
if (PLayerTransactionChild* manager = GetShadowManager()) {
|
||||
manager->SendClearCachedResources();
|
||||
}
|
||||
BasicLayerManager::ClearCachedResources(aSubtree);
|
||||
}
|
||||
|
||||
bool
|
||||
BasicShadowLayerManager::ProgressiveUpdateCallback(bool aHasPendingNewThebesContent,
|
||||
gfx::Rect& aViewport,
|
||||
float& aScaleX,
|
||||
float& aScaleY,
|
||||
bool aDrawingCritical)
|
||||
{
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
Layer* primaryScrollable = GetPrimaryScrollableLayer();
|
||||
if (primaryScrollable) {
|
||||
const FrameMetrics& metrics = primaryScrollable->AsContainerLayer()->GetFrameMetrics();
|
||||
|
||||
// This is derived from the code in
|
||||
// gfx/layers/ipc/CompositorParent.cpp::TransformShadowTree.
|
||||
const gfx3DMatrix& rootTransform = GetRoot()->GetTransform();
|
||||
float devPixelRatioX = 1 / rootTransform.GetXScale();
|
||||
float devPixelRatioY = 1 / rootTransform.GetYScale();
|
||||
const gfx::Rect& metricsDisplayPort =
|
||||
(aDrawingCritical && !metrics.mCriticalDisplayPort.IsEmpty()) ?
|
||||
metrics.mCriticalDisplayPort : metrics.mDisplayPort;
|
||||
gfx::Rect displayPort((metricsDisplayPort.x + metrics.mScrollOffset.x) * devPixelRatioX,
|
||||
(metricsDisplayPort.y + metrics.mScrollOffset.y) * devPixelRatioY,
|
||||
metricsDisplayPort.width * devPixelRatioX,
|
||||
metricsDisplayPort.height * devPixelRatioY);
|
||||
|
||||
return AndroidBridge::Bridge()->ProgressiveUpdateCallback(
|
||||
aHasPendingNewThebesContent, displayPort, devPixelRatioX, aDrawingCritical,
|
||||
aViewport, aScaleX, aScaleY);
|
||||
}
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
BasicShadowableLayer::~BasicShadowableLayer()
|
||||
{
|
||||
if (HasShadow()) {
|
||||
PLayerChild::Send__delete__(GetShadow());
|
||||
}
|
||||
MOZ_COUNT_DTOR(BasicShadowableLayer);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -204,134 +204,6 @@ protected:
|
||||
bool mCompositorMightResample;
|
||||
};
|
||||
|
||||
class BasicShadowLayerManager : public BasicLayerManager,
|
||||
public ShadowLayerForwarder
|
||||
{
|
||||
typedef nsTArray<nsRefPtr<Layer> > LayerRefArray;
|
||||
|
||||
public:
|
||||
BasicShadowLayerManager(nsIWidget* aWidget);
|
||||
virtual ~BasicShadowLayerManager();
|
||||
|
||||
virtual ShadowLayerForwarder* AsShadowForwarder()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
virtual int32_t GetMaxTextureSize() const;
|
||||
|
||||
virtual void SetDefaultTargetConfiguration(BufferMode aDoubleBuffering, ScreenRotation aRotation) MOZ_OVERRIDE;
|
||||
virtual void BeginTransactionWithTarget(gfxContext* aTarget);
|
||||
virtual bool EndEmptyTransaction(EndTransactionFlags aFlags = END_DEFAULT);
|
||||
virtual void EndTransaction(DrawThebesLayerCallback aCallback,
|
||||
void* aCallbackData,
|
||||
EndTransactionFlags aFlags = END_DEFAULT);
|
||||
|
||||
virtual void SetRoot(Layer* aLayer);
|
||||
|
||||
virtual void Mutated(Layer* aLayer);
|
||||
|
||||
virtual already_AddRefed<ThebesLayer> CreateThebesLayer();
|
||||
virtual already_AddRefed<ContainerLayer> CreateContainerLayer();
|
||||
virtual already_AddRefed<ImageLayer> CreateImageLayer();
|
||||
virtual already_AddRefed<CanvasLayer> CreateCanvasLayer();
|
||||
virtual already_AddRefed<ColorLayer> CreateColorLayer();
|
||||
virtual already_AddRefed<RefLayer> CreateRefLayer();
|
||||
|
||||
ShadowableLayer* Hold(Layer* aLayer);
|
||||
|
||||
bool HasShadowManager() const { return ShadowLayerForwarder::HasShadowManager(); }
|
||||
|
||||
virtual bool IsCompositingCheap();
|
||||
virtual bool HasShadowManagerInternal() const { return HasShadowManager(); }
|
||||
|
||||
virtual void SetIsFirstPaint() MOZ_OVERRIDE;
|
||||
|
||||
// Drop cached resources and ask our shadow manager to do the same,
|
||||
// if we have one.
|
||||
virtual void ClearCachedResources(Layer* aSubtree = nullptr) MOZ_OVERRIDE;
|
||||
|
||||
void SetRepeatTransaction() { mRepeatTransaction = true; }
|
||||
bool GetRepeatTransaction() { return mRepeatTransaction; }
|
||||
|
||||
bool IsRepeatTransaction() { return mIsRepeatTransaction; }
|
||||
|
||||
/**
|
||||
* Called for each iteration of a progressive tile update. Fills
|
||||
* aViewport, aScaleX and aScaleY with the current scale and viewport
|
||||
* being used to composite the layers in this manager, to determine what area
|
||||
* intersects with the target render rectangle. aDrawingCritical will be
|
||||
* true if the current drawing operation is using the critical displayport.
|
||||
* Returns true if the update should continue, or false if it should be
|
||||
* cancelled.
|
||||
* This is only called if gfxPlatform::UseProgressiveTilePainting() returns
|
||||
* true.
|
||||
*/
|
||||
bool ProgressiveUpdateCallback(bool aHasPendingNewThebesContent,
|
||||
gfx::Rect& aViewport,
|
||||
float& aScaleX,
|
||||
float& aScaleY,
|
||||
bool aDrawingCritical);
|
||||
|
||||
private:
|
||||
/**
|
||||
* Forward transaction results to the parent context.
|
||||
*/
|
||||
void ForwardTransaction();
|
||||
|
||||
/**
|
||||
* Take a snapshot of the parent context, and copy
|
||||
* it into mShadowTarget.
|
||||
*/
|
||||
void MakeSnapshotIfRequired();
|
||||
|
||||
// The bounds of |mTarget| in device pixels.
|
||||
nsIntRect mTargetBounds;
|
||||
|
||||
LayerRefArray mKeepAlive;
|
||||
|
||||
// Sometimes we draw to targets that don't natively support
|
||||
// landscape/portrait orientation. When we need to implement that
|
||||
// ourselves, |mTargetRotation| describes the induced transform we
|
||||
// need to apply when compositing content to our target.
|
||||
ScreenRotation mTargetRotation;
|
||||
|
||||
// Used to repeat the transaction right away (to avoid rebuilding
|
||||
// a display list) to support progressive drawing.
|
||||
bool mRepeatTransaction;
|
||||
bool mIsRepeatTransaction;
|
||||
};
|
||||
|
||||
class BasicShadowableThebesLayer;
|
||||
class BasicShadowableLayer : public ShadowableLayer
|
||||
{
|
||||
public:
|
||||
BasicShadowableLayer()
|
||||
{
|
||||
MOZ_COUNT_CTOR(BasicShadowableLayer);
|
||||
}
|
||||
|
||||
~BasicShadowableLayer();
|
||||
|
||||
void SetShadow(PLayerChild* aShadow)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(!mShadow, "can't have two shadows (yet)");
|
||||
mShadow = aShadow;
|
||||
}
|
||||
|
||||
virtual void Disconnect()
|
||||
{
|
||||
// This is an "emergency Disconnect()", called when the compositing
|
||||
// process has died. |mShadow| and our Shmem buffers are
|
||||
// automatically managed by IPDL, so we don't need to explicitly
|
||||
// free them here (it's hard to get that right on emergency
|
||||
// shutdown anyway).
|
||||
mShadow = nullptr;
|
||||
}
|
||||
|
||||
virtual BasicShadowableThebesLayer* AsThebes() { return nullptr; }
|
||||
};
|
||||
|
||||
void
|
||||
PaintContext(gfxPattern* aPattern,
|
||||
const nsIntRegion& aVisible,
|
||||
|
@ -129,47 +129,6 @@ FillWithMask(gfxContext* aContext, float aOpacity, Layer* aMaskLayer);
|
||||
BasicImplData*
|
||||
ToData(Layer* aLayer);
|
||||
|
||||
ShadowableLayer*
|
||||
ToShadowable(Layer* aLayer);
|
||||
|
||||
// Some layers, like ReadbackLayers, can't be shadowed and shadowing
|
||||
// them doesn't make sense anyway
|
||||
bool
|
||||
ShouldShadow(Layer* aLayer);
|
||||
|
||||
|
||||
template<class OpT> BasicShadowableLayer*
|
||||
GetBasicShadowable(const OpT& op)
|
||||
{
|
||||
return static_cast<BasicShadowableLayer*>(
|
||||
static_cast<const ShadowLayerChild*>(op.textureChild()->Manager())->layer());
|
||||
}
|
||||
|
||||
// Create a shadow layer (PLayerChild) for aLayer, if we're forwarding
|
||||
// our layer tree to a parent process. Record the new layer creation
|
||||
// in the current open transaction as a side effect.
|
||||
template<typename CreatedMethod> void
|
||||
MaybeCreateShadowFor(BasicShadowableLayer* aLayer,
|
||||
BasicShadowLayerManager* aMgr,
|
||||
CreatedMethod aMethod)
|
||||
{
|
||||
if (!aMgr->HasShadowManager()) {
|
||||
return;
|
||||
}
|
||||
|
||||
PLayerChild* shadow = aMgr->ConstructShadowFor(aLayer);
|
||||
// XXX error handling
|
||||
NS_ABORT_IF_FALSE(shadow, "failed to create shadow");
|
||||
|
||||
aLayer->SetShadow(shadow);
|
||||
(aMgr->*aMethod)(aLayer);
|
||||
aMgr->Hold(aLayer->AsLayer());
|
||||
}
|
||||
|
||||
#define MAYBE_CREATE_SHADOW(_type) \
|
||||
MaybeCreateShadowFor(layer, this, \
|
||||
&ShadowLayerForwarder::Created ## _type ## Layer)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4,7 +4,6 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "BasicThebesLayer.h"
|
||||
#include "BasicTiledThebesLayer.h"
|
||||
#include "gfxUtils.h"
|
||||
#include "nsIWidget.h"
|
||||
#include "RenderTrace.h"
|
||||
@ -74,9 +73,6 @@ BasicThebesLayer::PaintThebes(gfxContext* aContext,
|
||||
nsRefPtr<gfxASurface> targetSurface = aContext->CurrentSurface();
|
||||
|
||||
if (!mContentClient) {
|
||||
MOZ_ASSERT(!AsShadowableLayer() ||
|
||||
!static_cast<BasicShadowableThebesLayer*>(AsShadowableLayer())->HasShadow(),
|
||||
"OMTC layers must have a content client by now");
|
||||
// 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());
|
||||
@ -231,129 +227,6 @@ BasicThebesLayer::PaintThebes(gfxContext* aContext,
|
||||
}
|
||||
}
|
||||
|
||||
BasicShadowableThebesLayer::~BasicShadowableThebesLayer()
|
||||
{
|
||||
MOZ_COUNT_DTOR(BasicShadowableThebesLayer);
|
||||
}
|
||||
|
||||
void
|
||||
BasicShadowableThebesLayer::PaintThebes(gfxContext* aContext,
|
||||
Layer* aMaskLayer,
|
||||
LayerManager::DrawThebesLayerCallback aCallback,
|
||||
void* aCallbackData,
|
||||
ReadbackProcessor* aReadback)
|
||||
{
|
||||
if (!HasShadow()) {
|
||||
BasicThebesLayer::PaintThebes(aContext, aMaskLayer, aCallback, aCallbackData, aReadback);
|
||||
return;
|
||||
}
|
||||
|
||||
if (aMaskLayer) {
|
||||
static_cast<BasicImplData*>(aMaskLayer->ImplData())
|
||||
->Paint(aContext, nullptr);
|
||||
}
|
||||
|
||||
if (!mContentClient) {
|
||||
mContentClient = ContentClient::CreateContentClient(BasicManager());
|
||||
if (!mContentClient) {
|
||||
return;
|
||||
}
|
||||
mContentClient->Connect();
|
||||
BasicManager()->Attach(mContentClient, this);
|
||||
MOZ_ASSERT(mContentClient->GetForwarder());
|
||||
}
|
||||
|
||||
mContentClient->BeginPaint();
|
||||
BasicThebesLayer::PaintThebes(aContext, nullptr, aCallback, aCallbackData, aReadback);
|
||||
mContentClient->EndPaint();
|
||||
}
|
||||
|
||||
void
|
||||
BasicShadowableThebesLayer::PaintBuffer(gfxContext* aContext,
|
||||
const nsIntRegion& aRegionToDraw,
|
||||
const nsIntRegion& aExtendedRegionToDraw,
|
||||
const nsIntRegion& aRegionToInvalidate,
|
||||
bool aDidSelfCopy,
|
||||
LayerManager::DrawThebesLayerCallback aCallback,
|
||||
void* aCallbackData)
|
||||
{
|
||||
ContentClientRemote* contentClientRemote = static_cast<ContentClientRemote*>(mContentClient.get());
|
||||
MOZ_ASSERT(contentClientRemote->GetIPDLActor() || !HasShadow());
|
||||
|
||||
// NB: this just throws away the entire valid region if there are
|
||||
// too many rects.
|
||||
mValidRegion.SimplifyInward(8);
|
||||
|
||||
Base::PaintBuffer(aContext,
|
||||
aRegionToDraw, aExtendedRegionToDraw, aRegionToInvalidate,
|
||||
aDidSelfCopy,
|
||||
aCallback, aCallbackData);
|
||||
if (!HasShadow() || BasicManager()->IsTransactionIncomplete()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Hold(this) ensures this layer is kept alive through the current transaction
|
||||
// The ContentClient assumes this layer is kept alive (e.g., in CreateBuffer,
|
||||
// DestroyThebesBuffer), so deleting this Hold for whatever reason will break things.
|
||||
BasicManager()->Hold(this);
|
||||
contentClientRemote->Updated(aRegionToDraw,
|
||||
mVisibleRegion,
|
||||
aDidSelfCopy);
|
||||
}
|
||||
|
||||
void
|
||||
BasicShadowableThebesLayer::Disconnect()
|
||||
{
|
||||
mContentClient = nullptr;
|
||||
BasicShadowableLayer::Disconnect();
|
||||
}
|
||||
|
||||
class ShadowThebesLayerBuffer : public ThebesLayerBuffer
|
||||
{
|
||||
typedef ThebesLayerBuffer Base;
|
||||
|
||||
public:
|
||||
ShadowThebesLayerBuffer()
|
||||
: Base(ContainsVisibleBounds)
|
||||
{
|
||||
MOZ_COUNT_CTOR(ShadowThebesLayerBuffer);
|
||||
}
|
||||
|
||||
~ShadowThebesLayerBuffer()
|
||||
{
|
||||
MOZ_COUNT_DTOR(ShadowThebesLayerBuffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Swap in the old "virtual buffer" (see above) attributes in aNew*
|
||||
* and return the old ones in aOld*.
|
||||
*
|
||||
* Swap() must only be called when the buffer is in its "unmapped"
|
||||
* state, that is the underlying gfxASurface is not available. It
|
||||
* is expected that the owner of this buffer holds an unmapped
|
||||
* SurfaceDescriptor as the backing storage for this buffer. That's
|
||||
* why no gfxASurface or SurfaceDescriptor parameters appear here.
|
||||
*/
|
||||
void Swap(const nsIntRect& aNewRect, const nsIntPoint& aNewRotation,
|
||||
nsIntRect* aOldRect, nsIntPoint* aOldRotation)
|
||||
{
|
||||
*aOldRect = BufferRect();
|
||||
*aOldRotation = BufferRotation();
|
||||
|
||||
nsRefPtr<gfxASurface> oldBuffer;
|
||||
oldBuffer = SetBuffer(nullptr, aNewRect, aNewRotation);
|
||||
MOZ_ASSERT(!oldBuffer);
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual already_AddRefed<gfxASurface>
|
||||
CreateBuffer(ContentType, const nsIntRect&, uint32_t, gfxASurface**)
|
||||
{
|
||||
NS_RUNTIMEABORT("ThebesLayerComposite can't paint content");
|
||||
return nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
already_AddRefed<ThebesLayer>
|
||||
BasicLayerManager::CreateThebesLayer()
|
||||
{
|
||||
@ -362,29 +235,5 @@ BasicLayerManager::CreateThebesLayer()
|
||||
return layer.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<ThebesLayer>
|
||||
BasicShadowLayerManager::CreateThebesLayer()
|
||||
{
|
||||
NS_ASSERTION(InConstruction(), "Only allowed in construction phase");
|
||||
#ifdef FORCE_BASICTILEDTHEBESLAYER
|
||||
if (HasShadowManager() && GetCompositorBackendType() == LAYERS_OPENGL) {
|
||||
// BasicTiledThebesLayer doesn't support main
|
||||
// thread compositing so only return this layer
|
||||
// type if we have a shadow manager.
|
||||
nsRefPtr<BasicTiledThebesLayer> layer =
|
||||
new BasicTiledThebesLayer(this);
|
||||
MAYBE_CREATE_SHADOW(Thebes);
|
||||
return layer.forget();
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
nsRefPtr<BasicShadowableThebesLayer> layer =
|
||||
new BasicShadowableThebesLayer(this);
|
||||
MAYBE_CREATE_SHADOW(Thebes);
|
||||
return layer.forget();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -107,71 +107,6 @@ protected:
|
||||
RefPtr<ContentClient> mContentClient;
|
||||
};
|
||||
|
||||
class BasicShadowableThebesLayer : public BasicThebesLayer,
|
||||
public BasicShadowableLayer
|
||||
{
|
||||
typedef BasicThebesLayer Base;
|
||||
public:
|
||||
BasicShadowableThebesLayer(BasicShadowLayerManager* aManager)
|
||||
: BasicThebesLayer(aManager)
|
||||
{
|
||||
MOZ_COUNT_CTOR(BasicShadowableThebesLayer);
|
||||
}
|
||||
virtual ~BasicShadowableThebesLayer();
|
||||
|
||||
virtual void PaintThebes(gfxContext* aContext,
|
||||
Layer* aMaskLayer,
|
||||
LayerManager::DrawThebesLayerCallback aCallback,
|
||||
void* aCallbackData,
|
||||
ReadbackProcessor* aReadback);
|
||||
|
||||
virtual void ClearCachedResources() MOZ_OVERRIDE
|
||||
{
|
||||
BasicThebesLayer::ClearCachedResources();
|
||||
DestroyBackBuffer();
|
||||
// Don't try to read back from this, it soon may be invalid.
|
||||
// mROFrontBuffer = null_t();
|
||||
// mFrontAndBackBufferDiffer = false;
|
||||
}
|
||||
|
||||
virtual void FillSpecificAttributes(SpecificLayerAttributes& aAttrs)
|
||||
{
|
||||
aAttrs = ThebesLayerAttributes(GetValidRegion());
|
||||
}
|
||||
|
||||
virtual Layer* AsLayer() { return this; }
|
||||
virtual ShadowableLayer* AsShadowableLayer() { return this; }
|
||||
|
||||
virtual CompositableClient* GetCompositableClient() MOZ_OVERRIDE
|
||||
{
|
||||
return mContentClient;
|
||||
}
|
||||
|
||||
virtual void Disconnect();
|
||||
|
||||
virtual BasicShadowableThebesLayer* AsThebes() { return this; }
|
||||
|
||||
private:
|
||||
BasicShadowLayerManager* BasicManager()
|
||||
{
|
||||
return static_cast<BasicShadowLayerManager*>(mManager);
|
||||
}
|
||||
|
||||
virtual void
|
||||
PaintBuffer(gfxContext* aContext,
|
||||
const nsIntRegion& aRegionToDraw,
|
||||
const nsIntRegion& aExtendedRegionToDraw,
|
||||
const nsIntRegion& aRegionToInvalidate,
|
||||
bool aDidSelfCopy,
|
||||
LayerManager::DrawThebesLayerCallback aCallback,
|
||||
void* aCallbackData) MOZ_OVERRIDE;
|
||||
|
||||
void DestroyBackBuffer()
|
||||
{
|
||||
mContentClient = nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
#include "mozilla/layers/CanvasClient.h"
|
||||
#include "mozilla/layers/TextureClient.h"
|
||||
#include "BasicCanvasLayer.h"
|
||||
#include "ClientCanvasLayer.h"
|
||||
#include "mozilla/layers/ShadowLayers.h"
|
||||
#include "SharedTextureImage.h"
|
||||
#include "nsXULAppAPI.h"
|
||||
@ -49,7 +49,7 @@ CanvasClient2D::CanvasClient2D(CompositableForwarder* aFwd,
|
||||
}
|
||||
|
||||
void
|
||||
CanvasClient2D::Update(gfx::IntSize aSize, BasicCanvasLayer* aLayer)
|
||||
CanvasClient2D::Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer)
|
||||
{
|
||||
if (!mTextureClient) {
|
||||
mTextureClient = CreateTextureClient(TEXTURE_SHMEM);
|
||||
@ -63,7 +63,7 @@ CanvasClient2D::Update(gfx::IntSize aSize, BasicCanvasLayer* aLayer)
|
||||
mTextureClient->EnsureAllocated(aSize, contentType);
|
||||
|
||||
gfxASurface* surface = mTextureClient->LockSurface();
|
||||
static_cast<BasicCanvasLayer*>(aLayer)->UpdateSurface(surface, nullptr);
|
||||
aLayer->UpdateSurface(surface);
|
||||
mTextureClient->Unlock();
|
||||
}
|
||||
|
||||
@ -75,7 +75,7 @@ CanvasClientWebGL::CanvasClientWebGL(CompositableForwarder* aFwd,
|
||||
}
|
||||
|
||||
void
|
||||
CanvasClientWebGL::Update(gfx::IntSize aSize, BasicCanvasLayer* aLayer)
|
||||
CanvasClientWebGL::Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer)
|
||||
{
|
||||
if (!mTextureClient) {
|
||||
mTextureClient = CreateTextureClient(TEXTURE_STREAM_GL);
|
||||
|
@ -13,7 +13,7 @@ namespace mozilla {
|
||||
|
||||
namespace layers {
|
||||
|
||||
class BasicCanvasLayer;
|
||||
class ClientCanvasLayer;
|
||||
|
||||
/**
|
||||
* Compositable client for 2d and webgl canvas.
|
||||
@ -38,7 +38,7 @@ public:
|
||||
|
||||
virtual ~CanvasClient() {}
|
||||
|
||||
virtual void Update(gfx::IntSize aSize, BasicCanvasLayer* aLayer) = 0;
|
||||
virtual void Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer) = 0;
|
||||
|
||||
virtual void Updated();
|
||||
|
||||
@ -64,7 +64,7 @@ public:
|
||||
return mTextureInfo;
|
||||
}
|
||||
|
||||
virtual void Update(gfx::IntSize aSize, BasicCanvasLayer* aLayer);
|
||||
virtual void Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer);
|
||||
};
|
||||
|
||||
// Used for GL canvases where we don't need to do any readback, i.e., with a
|
||||
@ -80,7 +80,7 @@ public:
|
||||
return mTextureInfo;
|
||||
}
|
||||
|
||||
virtual void Update(gfx::IntSize aSize, BasicCanvasLayer* aLayer);
|
||||
virtual void Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer);
|
||||
};
|
||||
|
||||
}
|
||||
|
104
gfx/layers/client/ClientCanvasLayer.cpp
Normal file
104
gfx/layers/client/ClientCanvasLayer.cpp
Normal file
@ -0,0 +1,104 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* 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 "ClientCanvasLayer.h"
|
||||
#include "gfxPlatform.h"
|
||||
#include "SurfaceStream.h"
|
||||
#include "SharedSurfaceGL.h"
|
||||
#include "SharedSurfaceEGL.h"
|
||||
|
||||
using namespace mozilla::gl;
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
void
|
||||
ClientCanvasLayer::Initialize(const Data& aData)
|
||||
{
|
||||
CopyableCanvasLayer::Initialize(aData);
|
||||
|
||||
mCanvasClient = nullptr;
|
||||
|
||||
if (mGLContext) {
|
||||
GLScreenBuffer* screen = mGLContext->Screen();
|
||||
SurfaceStreamType streamType =
|
||||
SurfaceStream::ChooseGLStreamType(SurfaceStream::OffMainThread,
|
||||
screen->PreserveBuffer());
|
||||
SurfaceFactory_GL* factory = nullptr;
|
||||
if (!mForceReadback) {
|
||||
if (ClientManager()->GetCompositorBackendType() == mozilla::layers::LAYERS_OPENGL) {
|
||||
if (mGLContext->GetEGLContext()) {
|
||||
bool isCrossProcess = !(XRE_GetProcessType() == GeckoProcessType_Default);
|
||||
|
||||
if (!isCrossProcess) {
|
||||
// [Basic/OGL Layers, OMTC] WebGL layer init.
|
||||
factory = SurfaceFactory_EGLImage::Create(mGLContext, screen->Caps());
|
||||
} else {
|
||||
// [Basic/OGL Layers, OOPC] WebGL layer init. (Out Of Process Compositing)
|
||||
// Fall back to readback.
|
||||
}
|
||||
} else {
|
||||
// [Basic Layers, OMTC] WebGL layer init.
|
||||
// Well, this *should* work...
|
||||
factory = new SurfaceFactory_GLTexture(mGLContext, mGLContext, screen->Caps());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (factory) {
|
||||
screen->Morph(factory, streamType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ClientCanvasLayer::RenderLayer()
|
||||
{
|
||||
PROFILER_LABEL("ClientCanvasLayer", "Paint");
|
||||
if (!IsDirty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (GetMaskLayer()) {
|
||||
ToClientLayer(GetMaskLayer())->RenderLayer();
|
||||
}
|
||||
|
||||
if (!mCanvasClient) {
|
||||
TextureFlags flags = 0;
|
||||
if (mNeedsYFlip) {
|
||||
flags |= NeedsYFlip;
|
||||
}
|
||||
mCanvasClient = CanvasClient::CreateCanvasClient(GetCompositableClientType(),
|
||||
ClientManager(), flags);
|
||||
if (!mCanvasClient) {
|
||||
return;
|
||||
}
|
||||
if (HasShadow()) {
|
||||
mCanvasClient->Connect();
|
||||
ClientManager()->Attach(mCanvasClient, this);
|
||||
}
|
||||
}
|
||||
|
||||
FirePreTransactionCallback();
|
||||
mCanvasClient->Update(gfx::IntSize(mBounds.width, mBounds.height), this);
|
||||
|
||||
FireDidTransactionCallback();
|
||||
|
||||
ClientManager()->Hold(this);
|
||||
mCanvasClient->Updated();
|
||||
}
|
||||
|
||||
already_AddRefed<CanvasLayer>
|
||||
ClientLayerManager::CreateCanvasLayer()
|
||||
{
|
||||
NS_ASSERTION(InConstruction(), "Only allowed in construction phase");
|
||||
nsRefPtr<ClientCanvasLayer> layer =
|
||||
new ClientCanvasLayer(this);
|
||||
CREATE_SHADOW(Canvas);
|
||||
return layer.forget();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
90
gfx/layers/client/ClientCanvasLayer.h
Normal file
90
gfx/layers/client/ClientCanvasLayer.h
Normal file
@ -0,0 +1,90 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* 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_CLIENTCANVASLAYER_H
|
||||
#define GFX_CLIENTCANVASLAYER_H
|
||||
|
||||
#include "ClientLayerManager.h"
|
||||
#include "nsXULAppAPI.h"
|
||||
#include "gfxASurface.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/layers/LayerTransaction.h"
|
||||
#include "mozilla/layers/CanvasClient.h"
|
||||
#include "CopyableCanvasLayer.h"
|
||||
|
||||
using namespace mozilla::gfx;
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
class CanvasClient2D;
|
||||
class CanvasClientWebGL;
|
||||
|
||||
class ClientCanvasLayer : public CopyableCanvasLayer,
|
||||
public ClientLayer
|
||||
{
|
||||
public:
|
||||
ClientCanvasLayer(ClientLayerManager* aLayerManager) :
|
||||
CopyableCanvasLayer(aLayerManager, static_cast<ClientLayer*>(this))
|
||||
{
|
||||
MOZ_COUNT_CTOR(ClientCanvasLayer);
|
||||
}
|
||||
virtual ~ClientCanvasLayer()
|
||||
{
|
||||
MOZ_COUNT_DTOR(ClientCanvasLayer);
|
||||
}
|
||||
|
||||
virtual void SetVisibleRegion(const nsIntRegion& aRegion)
|
||||
{
|
||||
NS_ASSERTION(ClientManager()->InConstruction(),
|
||||
"Can only set properties in construction phase");
|
||||
CanvasLayer::SetVisibleRegion(aRegion);
|
||||
}
|
||||
|
||||
virtual void Initialize(const Data& aData);
|
||||
|
||||
virtual void RenderLayer();
|
||||
|
||||
virtual void FillSpecificAttributes(SpecificLayerAttributes& aAttrs)
|
||||
{
|
||||
aAttrs = CanvasLayerAttributes(mFilter, mBounds);
|
||||
}
|
||||
|
||||
virtual Layer* AsLayer() { return this; }
|
||||
virtual ShadowableLayer* AsShadowableLayer() { return this; }
|
||||
|
||||
virtual void Disconnect()
|
||||
{
|
||||
mCanvasClient = nullptr;
|
||||
ClientLayer::Disconnect();
|
||||
}
|
||||
|
||||
virtual CompositableClient* GetCompositableClient() MOZ_OVERRIDE
|
||||
{
|
||||
return mCanvasClient;
|
||||
}
|
||||
protected:
|
||||
ClientLayerManager* ClientManager()
|
||||
{
|
||||
return static_cast<ClientLayerManager*>(mManager);
|
||||
}
|
||||
|
||||
CompositableType GetCompositableClientType()
|
||||
{
|
||||
if (mGLContext && XRE_GetProcessType() == GeckoProcessType_Default) {
|
||||
return BUFFER_IMAGE_BUFFERED;
|
||||
}
|
||||
return BUFFER_IMAGE_SINGLE;
|
||||
}
|
||||
|
||||
RefPtr<CanvasClient> mCanvasClient;
|
||||
|
||||
friend class CanvasClient2D;
|
||||
friend class CanvasClientWebGL;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
72
gfx/layers/client/ClientColorLayer.cpp
Normal file
72
gfx/layers/client/ClientColorLayer.cpp
Normal file
@ -0,0 +1,72 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* 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 "ClientLayerManager.h"
|
||||
#include "mozilla/layers/LayerTransaction.h"
|
||||
|
||||
using namespace mozilla::gfx;
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
class ClientColorLayer : public ColorLayer,
|
||||
public ClientLayer {
|
||||
public:
|
||||
ClientColorLayer(ClientLayerManager* aLayerManager) :
|
||||
ColorLayer(aLayerManager, static_cast<ClientLayer*>(this))
|
||||
{
|
||||
MOZ_COUNT_CTOR(ClientColorLayer);
|
||||
}
|
||||
virtual ~ClientColorLayer()
|
||||
{
|
||||
MOZ_COUNT_DTOR(ClientColorLayer);
|
||||
}
|
||||
|
||||
virtual void SetVisibleRegion(const nsIntRegion& aRegion)
|
||||
{
|
||||
NS_ASSERTION(ClientManager()->InConstruction(),
|
||||
"Can only set properties in construction phase");
|
||||
ColorLayer::SetVisibleRegion(aRegion);
|
||||
}
|
||||
|
||||
virtual void RenderLayer()
|
||||
{
|
||||
if (GetMaskLayer()) {
|
||||
ToClientLayer(GetMaskLayer())->RenderLayer();
|
||||
}
|
||||
}
|
||||
|
||||
virtual void FillSpecificAttributes(SpecificLayerAttributes& aAttrs)
|
||||
{
|
||||
aAttrs = ColorLayerAttributes(GetColor());
|
||||
}
|
||||
|
||||
virtual Layer* AsLayer() { return this; }
|
||||
virtual ShadowableLayer* AsShadowableLayer() { return this; }
|
||||
|
||||
virtual void Disconnect()
|
||||
{
|
||||
ClientLayer::Disconnect();
|
||||
}
|
||||
|
||||
protected:
|
||||
ClientLayerManager* ClientManager()
|
||||
{
|
||||
return static_cast<ClientLayerManager*>(mManager);
|
||||
}
|
||||
};
|
||||
|
||||
already_AddRefed<ColorLayer>
|
||||
ClientLayerManager::CreateColorLayer()
|
||||
{
|
||||
NS_ASSERTION(InConstruction(), "Only allowed in construction phase");
|
||||
nsRefPtr<ClientColorLayer> layer =
|
||||
new ClientColorLayer(this);
|
||||
CREATE_SHADOW(Color);
|
||||
return layer.forget();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
22
gfx/layers/client/ClientContainerLayer.cpp
Normal file
22
gfx/layers/client/ClientContainerLayer.cpp
Normal file
@ -0,0 +1,22 @@
|
||||
#include "ClientContainerLayer.h"
|
||||
#include "BasicLayersImpl.h"
|
||||
|
||||
already_AddRefed<ContainerLayer>
|
||||
ClientLayerManager::CreateContainerLayer()
|
||||
{
|
||||
NS_ASSERTION(InConstruction(), "Only allowed in construction phase");
|
||||
nsRefPtr<ClientContainerLayer> layer =
|
||||
new ClientContainerLayer(this);
|
||||
CREATE_SHADOW(Container);
|
||||
return layer.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<RefLayer>
|
||||
ClientLayerManager::CreateRefLayer()
|
||||
{
|
||||
NS_ASSERTION(InConstruction(), "Only allowed in construction phase");
|
||||
nsRefPtr<ClientRefLayer> layer =
|
||||
new ClientRefLayer(this);
|
||||
CREATE_SHADOW(Ref);
|
||||
return layer.forget();
|
||||
}
|
278
gfx/layers/client/ClientContainerLayer.h
Normal file
278
gfx/layers/client/ClientContainerLayer.h
Normal file
@ -0,0 +1,278 @@
|
||||
#include "ClientLayerManager.h"
|
||||
#include "gfxPlatform.h"
|
||||
|
||||
using namespace mozilla::layers;
|
||||
|
||||
template<class Container> void
|
||||
ContainerInsertAfter(Layer* aChild, Layer* aAfter, Container* aContainer)
|
||||
{
|
||||
NS_ASSERTION(aChild->Manager() == aContainer->Manager(),
|
||||
"Child has wrong manager");
|
||||
NS_ASSERTION(!aChild->GetParent(),
|
||||
"aChild already in the tree");
|
||||
NS_ASSERTION(!aChild->GetNextSibling() && !aChild->GetPrevSibling(),
|
||||
"aChild already has siblings?");
|
||||
NS_ASSERTION(!aAfter ||
|
||||
(aAfter->Manager() == aContainer->Manager() &&
|
||||
aAfter->GetParent() == aContainer),
|
||||
"aAfter is not our child");
|
||||
|
||||
aChild->SetParent(aContainer);
|
||||
if (aAfter == aContainer->mLastChild) {
|
||||
aContainer->mLastChild = aChild;
|
||||
}
|
||||
if (!aAfter) {
|
||||
aChild->SetNextSibling(aContainer->mFirstChild);
|
||||
if (aContainer->mFirstChild) {
|
||||
aContainer->mFirstChild->SetPrevSibling(aChild);
|
||||
}
|
||||
aContainer->mFirstChild = aChild;
|
||||
NS_ADDREF(aChild);
|
||||
aContainer->DidInsertChild(aChild);
|
||||
return;
|
||||
}
|
||||
|
||||
Layer* next = aAfter->GetNextSibling();
|
||||
aChild->SetNextSibling(next);
|
||||
aChild->SetPrevSibling(aAfter);
|
||||
if (next) {
|
||||
next->SetPrevSibling(aChild);
|
||||
}
|
||||
aAfter->SetNextSibling(aChild);
|
||||
NS_ADDREF(aChild);
|
||||
aContainer->DidInsertChild(aChild);
|
||||
}
|
||||
|
||||
template<class Container> void
|
||||
ContainerRemoveChild(Layer* aChild, Container* aContainer)
|
||||
{
|
||||
NS_ASSERTION(aChild->Manager() == aContainer->Manager(),
|
||||
"Child has wrong manager");
|
||||
NS_ASSERTION(aChild->GetParent() == aContainer,
|
||||
"aChild not our child");
|
||||
|
||||
Layer* prev = aChild->GetPrevSibling();
|
||||
Layer* next = aChild->GetNextSibling();
|
||||
if (prev) {
|
||||
prev->SetNextSibling(next);
|
||||
} else {
|
||||
aContainer->mFirstChild = next;
|
||||
}
|
||||
if (next) {
|
||||
next->SetPrevSibling(prev);
|
||||
} else {
|
||||
aContainer->mLastChild = prev;
|
||||
}
|
||||
|
||||
aChild->SetNextSibling(nullptr);
|
||||
aChild->SetPrevSibling(nullptr);
|
||||
aChild->SetParent(nullptr);
|
||||
|
||||
aContainer->DidRemoveChild(aChild);
|
||||
NS_RELEASE(aChild);
|
||||
}
|
||||
|
||||
template<class Container> void
|
||||
ContainerRepositionChild(Layer* aChild, Layer* aAfter, Container* aContainer)
|
||||
{
|
||||
NS_ASSERTION(aChild->Manager() == aContainer->Manager(),
|
||||
"Child has wrong manager");
|
||||
NS_ASSERTION(aChild->GetParent() == aContainer,
|
||||
"aChild not our child");
|
||||
NS_ASSERTION(!aAfter ||
|
||||
(aAfter->Manager() == aContainer->Manager() &&
|
||||
aAfter->GetParent() == aContainer),
|
||||
"aAfter is not our child");
|
||||
|
||||
Layer* prev = aChild->GetPrevSibling();
|
||||
Layer* next = aChild->GetNextSibling();
|
||||
if (prev == aAfter) {
|
||||
// aChild is already in the correct position, nothing to do.
|
||||
return;
|
||||
}
|
||||
if (prev) {
|
||||
prev->SetNextSibling(next);
|
||||
}
|
||||
if (next) {
|
||||
next->SetPrevSibling(prev);
|
||||
}
|
||||
if (!aAfter) {
|
||||
aChild->SetPrevSibling(nullptr);
|
||||
aChild->SetNextSibling(aContainer->mFirstChild);
|
||||
if (aContainer->mFirstChild) {
|
||||
aContainer->mFirstChild->SetPrevSibling(aChild);
|
||||
}
|
||||
aContainer->mFirstChild = aChild;
|
||||
return;
|
||||
}
|
||||
|
||||
Layer* afterNext = aAfter->GetNextSibling();
|
||||
if (afterNext) {
|
||||
afterNext->SetPrevSibling(aChild);
|
||||
} else {
|
||||
aContainer->mLastChild = aChild;
|
||||
}
|
||||
aAfter->SetNextSibling(aChild);
|
||||
aChild->SetPrevSibling(aAfter);
|
||||
aChild->SetNextSibling(afterNext);
|
||||
}
|
||||
|
||||
static bool
|
||||
HasOpaqueAncestorLayer(Layer* aLayer)
|
||||
{
|
||||
for (Layer* l = aLayer->GetParent(); l; l = l->GetParent()) {
|
||||
if (l->GetContentFlags() & Layer::CONTENT_OPAQUE)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
class ClientContainerLayer : public ContainerLayer,
|
||||
public ClientLayer
|
||||
{
|
||||
template<class Container>
|
||||
friend void ContainerInsertAfter(Layer* aChild, Layer* aAfter, Container* aContainer);
|
||||
template<class Container>
|
||||
friend void ContainerRemoveChild(Layer* aChild, Container* aContainer);
|
||||
template<class Container>
|
||||
friend void ContainerRepositionChild(Layer* aChild, Layer* aAfter, Container* aContainer);
|
||||
|
||||
public:
|
||||
ClientContainerLayer(ClientLayerManager* aManager) :
|
||||
ContainerLayer(aManager, static_cast<ClientLayer*>(this))
|
||||
{
|
||||
MOZ_COUNT_CTOR(ClientContainerLayer);
|
||||
mSupportsComponentAlphaChildren = true;
|
||||
}
|
||||
virtual ~ClientContainerLayer()
|
||||
{
|
||||
while (mFirstChild) {
|
||||
ContainerRemoveChild(mFirstChild, this);
|
||||
}
|
||||
|
||||
MOZ_COUNT_DTOR(ClientContainerLayer);
|
||||
}
|
||||
|
||||
virtual void RenderLayer()
|
||||
{
|
||||
// Setup mSupportsComponentAlphaChildren in the same way
|
||||
// that ContainerLayerComposite will do.
|
||||
if (UseIntermediateSurface()) {
|
||||
if (GetEffectiveVisibleRegion().GetNumRects() != 1 ||
|
||||
!(GetContentFlags() & Layer::CONTENT_OPAQUE))
|
||||
{
|
||||
const gfx3DMatrix& transform3D = GetEffectiveTransform();
|
||||
gfxMatrix transform;
|
||||
if (HasOpaqueAncestorLayer(this) &&
|
||||
transform3D.Is2D(&transform) &&
|
||||
!transform.HasNonIntegerTranslation()) {
|
||||
SetSupportsComponentAlphaChildren(
|
||||
gfxPlatform::GetPlatform()->UsesSubpixelAATextRendering());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
SetSupportsComponentAlphaChildren(
|
||||
(GetContentFlags() & Layer::CONTENT_OPAQUE) ||
|
||||
(GetParent() && GetParent()->SupportsComponentAlphaChildren()));
|
||||
}
|
||||
|
||||
nsAutoTArray<Layer*, 12> children;
|
||||
SortChildrenBy3DZOrder(children);
|
||||
|
||||
for (uint32_t i = 0; i < children.Length(); i++) {
|
||||
if (children.ElementAt(i)->GetEffectiveVisibleRegion().IsEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ToClientLayer(children.ElementAt(i))->RenderLayer();
|
||||
}
|
||||
}
|
||||
|
||||
virtual void SetVisibleRegion(const nsIntRegion& aRegion)
|
||||
{
|
||||
NS_ASSERTION(ClientManager()->InConstruction(),
|
||||
"Can only set properties in construction phase");
|
||||
ContainerLayer::SetVisibleRegion(aRegion);
|
||||
}
|
||||
virtual void InsertAfter(Layer* aChild, Layer* aAfter)
|
||||
{
|
||||
NS_ASSERTION(ClientManager()->InConstruction(),
|
||||
"Can only set properties in construction phase");
|
||||
ClientManager()->InsertAfter(ClientManager()->Hold(this),
|
||||
ClientManager()->Hold(aChild),
|
||||
aAfter ? ClientManager()->Hold(aAfter) : nullptr);
|
||||
ContainerInsertAfter(aChild, aAfter, this);
|
||||
}
|
||||
|
||||
virtual void RemoveChild(Layer* aChild)
|
||||
{
|
||||
NS_ASSERTION(ClientManager()->InConstruction(),
|
||||
"Can only set properties in construction phase");
|
||||
ClientManager()->RemoveChild(ClientManager()->Hold(this),
|
||||
ClientManager()->Hold(aChild));
|
||||
ContainerRemoveChild(aChild, this);
|
||||
}
|
||||
|
||||
virtual void RepositionChild(Layer* aChild, Layer* aAfter)
|
||||
{
|
||||
NS_ASSERTION(ClientManager()->InConstruction(),
|
||||
"Can only set properties in construction phase");
|
||||
ClientManager()->RepositionChild(ClientManager()->Hold(this),
|
||||
ClientManager()->Hold(aChild),
|
||||
aAfter ? ClientManager()->Hold(aAfter) : nullptr);
|
||||
ContainerRepositionChild(aChild, aAfter, this);
|
||||
}
|
||||
|
||||
virtual Layer* AsLayer() { return this; }
|
||||
virtual ShadowableLayer* AsShadowableLayer() { return this; }
|
||||
|
||||
virtual void ComputeEffectiveTransforms(const gfx3DMatrix& aTransformToSurface)
|
||||
{
|
||||
DefaultComputeEffectiveTransforms(aTransformToSurface);
|
||||
}
|
||||
|
||||
void ForceIntermediateSurface() { mUseIntermediateSurface = true; }
|
||||
|
||||
void SetSupportsComponentAlphaChildren(bool aSupports) { mSupportsComponentAlphaChildren = aSupports; }
|
||||
|
||||
protected:
|
||||
ClientLayerManager* ClientManager()
|
||||
{
|
||||
return static_cast<ClientLayerManager*>(mManager);
|
||||
}
|
||||
};
|
||||
|
||||
class ClientRefLayer : public RefLayer,
|
||||
public ClientLayer {
|
||||
public:
|
||||
ClientRefLayer(ClientLayerManager* aManager) :
|
||||
RefLayer(aManager, static_cast<ClientLayer*>(this))
|
||||
{
|
||||
MOZ_COUNT_CTOR(ClientRefLayer);
|
||||
}
|
||||
virtual ~ClientRefLayer()
|
||||
{
|
||||
MOZ_COUNT_DTOR(ClientRefLayer);
|
||||
}
|
||||
|
||||
virtual Layer* AsLayer() { return this; }
|
||||
virtual ShadowableLayer* AsShadowableLayer() { return this; }
|
||||
|
||||
virtual void Disconnect()
|
||||
{
|
||||
ClientLayer::Disconnect();
|
||||
}
|
||||
|
||||
virtual void RenderLayer() { }
|
||||
|
||||
virtual void ComputeEffectiveTransforms(const gfx3DMatrix& aTransformToSurface)
|
||||
{
|
||||
DefaultComputeEffectiveTransforms(aTransformToSurface);
|
||||
}
|
||||
|
||||
private:
|
||||
ClientLayerManager* ClientManager()
|
||||
{
|
||||
return static_cast<ClientLayerManager*>(mManager);
|
||||
}
|
||||
};
|
150
gfx/layers/client/ClientImageLayer.cpp
Normal file
150
gfx/layers/client/ClientImageLayer.cpp
Normal file
@ -0,0 +1,150 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* 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 "ClientLayerManager.h"
|
||||
#include "mozilla/layers/LayerTransaction.h"
|
||||
#include "mozilla/layers/ImageClient.h"
|
||||
#include "ImageContainer.h"
|
||||
|
||||
using namespace mozilla::gfx;
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
class ClientImageLayer : public ImageLayer,
|
||||
public ClientLayer {
|
||||
public:
|
||||
ClientImageLayer(ClientLayerManager* aLayerManager)
|
||||
: ImageLayer(aLayerManager, static_cast<ClientLayer*>(this))
|
||||
, mImageClientTypeContainer(BUFFER_UNKNOWN)
|
||||
{
|
||||
MOZ_COUNT_CTOR(ClientImageLayer);
|
||||
}
|
||||
virtual ~ClientImageLayer()
|
||||
{
|
||||
DestroyBackBuffer();
|
||||
MOZ_COUNT_DTOR(ClientImageLayer);
|
||||
}
|
||||
|
||||
virtual void SetContainer(ImageContainer* aContainer) MOZ_OVERRIDE
|
||||
{
|
||||
ImageLayer::SetContainer(aContainer);
|
||||
mImageClientTypeContainer = BUFFER_UNKNOWN;
|
||||
}
|
||||
|
||||
virtual void SetVisibleRegion(const nsIntRegion& aRegion)
|
||||
{
|
||||
NS_ASSERTION(ClientManager()->InConstruction(),
|
||||
"Can only set properties in construction phase");
|
||||
ImageLayer::SetVisibleRegion(aRegion);
|
||||
}
|
||||
|
||||
virtual void RenderLayer();
|
||||
|
||||
virtual void ClearCachedResources() MOZ_OVERRIDE
|
||||
{
|
||||
DestroyBackBuffer();
|
||||
}
|
||||
|
||||
virtual void FillSpecificAttributes(SpecificLayerAttributes& aAttrs)
|
||||
{
|
||||
aAttrs = ImageLayerAttributes(mFilter);
|
||||
}
|
||||
|
||||
virtual Layer* AsLayer() { return this; }
|
||||
virtual ShadowableLayer* AsShadowableLayer() { return this; }
|
||||
|
||||
virtual void Disconnect()
|
||||
{
|
||||
DestroyBackBuffer();
|
||||
ClientLayer::Disconnect();
|
||||
}
|
||||
|
||||
void DestroyBackBuffer()
|
||||
{
|
||||
mImageClient = nullptr;
|
||||
}
|
||||
|
||||
virtual CompositableClient* GetCompositableClient() MOZ_OVERRIDE
|
||||
{
|
||||
return mImageClient;
|
||||
}
|
||||
|
||||
protected:
|
||||
ClientLayerManager* ClientManager()
|
||||
{
|
||||
return static_cast<ClientLayerManager*>(mManager);
|
||||
}
|
||||
|
||||
CompositableType GetImageClientType()
|
||||
{
|
||||
if (mImageClientTypeContainer != BUFFER_UNKNOWN) {
|
||||
return mImageClientTypeContainer;
|
||||
}
|
||||
|
||||
if (mContainer->IsAsync()) {
|
||||
mImageClientTypeContainer = BUFFER_BRIDGE;
|
||||
return mImageClientTypeContainer;
|
||||
}
|
||||
|
||||
nsRefPtr<gfxASurface> surface;
|
||||
AutoLockImage autoLock(mContainer, getter_AddRefs(surface));
|
||||
|
||||
mImageClientTypeContainer = autoLock.GetImage() ?
|
||||
BUFFER_IMAGE_SINGLE : BUFFER_UNKNOWN;
|
||||
return mImageClientTypeContainer;
|
||||
}
|
||||
|
||||
RefPtr<ImageClient> mImageClient;
|
||||
CompositableType mImageClientTypeContainer;
|
||||
};
|
||||
|
||||
void
|
||||
ClientImageLayer::RenderLayer()
|
||||
{
|
||||
if (GetMaskLayer()) {
|
||||
ToClientLayer(GetMaskLayer())->RenderLayer();
|
||||
}
|
||||
|
||||
if (!mContainer) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mImageClient ||
|
||||
!mImageClient->UpdateImage(mContainer, GetContentFlags())) {
|
||||
mImageClient = ImageClient::CreateImageClient(GetImageClientType(),
|
||||
ClientManager(),
|
||||
mForceSingleTile
|
||||
? ForceSingleTile
|
||||
: 0);
|
||||
if (GetImageClientType() == BUFFER_BRIDGE) {
|
||||
static_cast<ImageClientBridge*>(mImageClient.get())->SetLayer(this);
|
||||
}
|
||||
|
||||
if (!mImageClient) {
|
||||
return;
|
||||
}
|
||||
if (HasShadow() && !mContainer->IsAsync()) {
|
||||
mImageClient->Connect();
|
||||
ClientManager()->Attach(mImageClient, this);
|
||||
}
|
||||
if (!mImageClient->UpdateImage(mContainer, GetContentFlags())) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
ClientManager()->Hold(this);
|
||||
}
|
||||
|
||||
already_AddRefed<ImageLayer>
|
||||
ClientLayerManager::CreateImageLayer()
|
||||
{
|
||||
NS_ASSERTION(InConstruction(), "Only allowed in construction phase");
|
||||
nsRefPtr<ClientImageLayer> layer =
|
||||
new ClientImageLayer(this);
|
||||
CREATE_SHADOW(Image);
|
||||
return layer.forget();
|
||||
}
|
||||
}
|
||||
}
|
424
gfx/layers/client/ClientLayerManager.cpp
Normal file
424
gfx/layers/client/ClientLayerManager.cpp
Normal file
@ -0,0 +1,424 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* 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 "ClientLayerManager.h"
|
||||
#include "nsIWidget.h"
|
||||
#include "mozilla/dom/TabChild.h"
|
||||
#include "mozilla/Hal.h"
|
||||
#include "mozilla/layers/PLayerChild.h"
|
||||
#include "mozilla/layers/PLayerTransactionChild.h"
|
||||
#include "mozilla/layers/PLayerTransactionParent.h"
|
||||
#include "CompositorChild.h"
|
||||
#include "ipc/AutoOpenSurface.h"
|
||||
#include "ipc/ShadowLayerChild.h"
|
||||
#include "mozilla/layers/CompositableClient.h"
|
||||
#include "mozilla/layers/ContentClient.h"
|
||||
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
#include "AndroidBridge.h"
|
||||
#endif
|
||||
|
||||
using namespace mozilla::dom;
|
||||
using namespace mozilla::gfx;
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
ClientLayerManager::ClientLayerManager(nsIWidget* aWidget)
|
||||
: mPhase(PHASE_NONE)
|
||||
, mWidget(aWidget)
|
||||
, mTargetRotation(ROTATION_0)
|
||||
, mRepeatTransaction(false)
|
||||
, mIsRepeatTransaction(false)
|
||||
, mTransactionIncomplete(false)
|
||||
, mCompositorMightResample(false)
|
||||
{
|
||||
MOZ_COUNT_CTOR(ClientLayerManager);
|
||||
}
|
||||
|
||||
ClientLayerManager::~ClientLayerManager()
|
||||
{
|
||||
mRoot = nullptr;
|
||||
|
||||
MOZ_COUNT_DTOR(ClientLayerManager);
|
||||
}
|
||||
|
||||
int32_t
|
||||
ClientLayerManager::GetMaxTextureSize() const
|
||||
{
|
||||
return ShadowLayerForwarder::GetMaxTextureSize();
|
||||
}
|
||||
|
||||
void
|
||||
ClientLayerManager::SetDefaultTargetConfiguration(BufferMode aDoubleBuffering,
|
||||
ScreenRotation aRotation)
|
||||
{
|
||||
mTargetRotation = aRotation;
|
||||
if (mWidget) {
|
||||
mTargetBounds = mWidget->GetNaturalBounds();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ClientLayerManager::SetRoot(Layer* aLayer)
|
||||
{
|
||||
if (mRoot != aLayer) {
|
||||
// Have to hold the old root and its children in order to
|
||||
// maintain the same view of the layer tree in this process as
|
||||
// the parent sees. Otherwise layers can be destroyed
|
||||
// mid-transaction and bad things can happen (v. bug 612573)
|
||||
if (mRoot) {
|
||||
Hold(mRoot);
|
||||
}
|
||||
ShadowLayerForwarder::SetRoot(Hold(aLayer));
|
||||
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
|
||||
ClientLayerManager::Mutated(Layer* aLayer)
|
||||
{
|
||||
LayerManager::Mutated(aLayer);
|
||||
|
||||
NS_ASSERTION(InConstruction() || InDrawing(), "wrong phase");
|
||||
ShadowLayerForwarder::Mutated(Hold(aLayer));
|
||||
}
|
||||
|
||||
void
|
||||
ClientLayerManager::BeginTransactionWithTarget(gfxContext* aTarget)
|
||||
{
|
||||
mInTransaction = true;
|
||||
|
||||
#ifdef MOZ_LAYERS_HAVE_LOG
|
||||
MOZ_LAYERS_LOG(("[----- BeginTransaction"));
|
||||
Log();
|
||||
#endif
|
||||
|
||||
NS_ASSERTION(!InTransaction(), "Nested transactions not allowed");
|
||||
mPhase = PHASE_CONSTRUCTION;
|
||||
|
||||
NS_ABORT_IF_FALSE(mKeepAlive.IsEmpty(), "uncommitted txn?");
|
||||
nsRefPtr<gfxContext> targetContext = aTarget;
|
||||
|
||||
// If the last transaction was incomplete (a failed DoEmptyTransaction),
|
||||
// don't signal a new transaction to ShadowLayerForwarder. Carry on adding
|
||||
// to the previous transaction.
|
||||
ScreenOrientation orientation;
|
||||
nsIntRect clientBounds;
|
||||
if (TabChild* window = mWidget->GetOwningTabChild()) {
|
||||
orientation = window->GetOrientation();
|
||||
} else {
|
||||
hal::ScreenConfiguration currentConfig;
|
||||
hal::GetCurrentScreenConfiguration(¤tConfig);
|
||||
orientation = currentConfig.orientation();
|
||||
}
|
||||
mWidget->GetClientBounds(clientBounds);
|
||||
ShadowLayerForwarder::BeginTransaction(mTargetBounds, mTargetRotation, clientBounds, orientation);
|
||||
|
||||
// If we're drawing on behalf of a context with async pan/zoom
|
||||
// enabled, then the entire buffer of thebes layers might be
|
||||
// composited (including resampling) asynchronously before we get
|
||||
// a chance to repaint, so we have to ensure that it's all valid
|
||||
// and not rotated.
|
||||
if (mWidget) {
|
||||
if (TabChild* window = mWidget->GetOwningTabChild()) {
|
||||
mCompositorMightResample = window->IsAsyncPanZoomEnabled();
|
||||
}
|
||||
}
|
||||
|
||||
// If we have a non-default target, we need to let our shadow manager draw
|
||||
// to it. This will happen at the end of the transaction.
|
||||
if (aTarget && XRE_GetProcessType() == GeckoProcessType_Default) {
|
||||
mShadowTarget = aTarget;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ClientLayerManager::BeginTransaction()
|
||||
{
|
||||
mInTransaction = true;
|
||||
BeginTransactionWithTarget(nullptr);
|
||||
}
|
||||
|
||||
bool
|
||||
ClientLayerManager::EndTransactionInternal(DrawThebesLayerCallback aCallback,
|
||||
void* aCallbackData,
|
||||
EndTransactionFlags)
|
||||
{
|
||||
PROFILER_LABEL("ClientLayerManager", "EndTransactionInternal");
|
||||
#ifdef MOZ_LAYERS_HAVE_LOG
|
||||
MOZ_LAYERS_LOG((" ----- (beginning paint)"));
|
||||
Log();
|
||||
#endif
|
||||
|
||||
NS_ASSERTION(InConstruction(), "Should be in construction phase");
|
||||
mPhase = PHASE_DRAWING;
|
||||
|
||||
ClientLayer* root = ClientLayer::ToClientLayer(GetRoot());
|
||||
|
||||
mTransactionIncomplete = false;
|
||||
|
||||
// Apply pending tree updates before recomputing effective
|
||||
// properties.
|
||||
GetRoot()->ApplyPendingUpdatesToSubtree();
|
||||
|
||||
mThebesLayerCallback = aCallback;
|
||||
mThebesLayerCallbackData = aCallbackData;
|
||||
|
||||
GetRoot()->ComputeEffectiveTransforms(gfx3DMatrix());
|
||||
|
||||
root->RenderLayer();
|
||||
|
||||
mThebesLayerCallback = nullptr;
|
||||
mThebesLayerCallbackData = nullptr;
|
||||
|
||||
// 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;
|
||||
|
||||
NS_ASSERTION(!aCallback || !mTransactionIncomplete,
|
||||
"If callback is not null, transaction must be complete");
|
||||
|
||||
return !mTransactionIncomplete;
|
||||
}
|
||||
|
||||
void
|
||||
ClientLayerManager::EndTransaction(DrawThebesLayerCallback aCallback,
|
||||
void* aCallbackData,
|
||||
EndTransactionFlags aFlags)
|
||||
{
|
||||
if (mWidget) {
|
||||
mWidget->PrepareWindowEffects();
|
||||
}
|
||||
EndTransactionInternal(aCallback, aCallbackData, aFlags);
|
||||
ForwardTransaction();
|
||||
|
||||
if (mRepeatTransaction) {
|
||||
mRepeatTransaction = false;
|
||||
mIsRepeatTransaction = true;
|
||||
BeginTransaction();
|
||||
ClientLayerManager::EndTransaction(aCallback, aCallbackData, aFlags);
|
||||
mIsRepeatTransaction = false;
|
||||
} else {
|
||||
MakeSnapshotIfRequired();
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
ClientLayerManager::EndEmptyTransaction(EndTransactionFlags aFlags)
|
||||
{
|
||||
mInTransaction = false;
|
||||
|
||||
if (!mRoot) {
|
||||
return false;
|
||||
}
|
||||
if (!EndTransactionInternal(nullptr, nullptr, aFlags)) {
|
||||
// Return without calling ForwardTransaction. This leaves the
|
||||
// ShadowLayerForwarder transaction open; the following
|
||||
// EndTransaction will complete it.
|
||||
return false;
|
||||
}
|
||||
ForwardTransaction();
|
||||
MakeSnapshotIfRequired();
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
ClientLayerManager::MakeSnapshotIfRequired()
|
||||
{
|
||||
if (!mShadowTarget) {
|
||||
return;
|
||||
}
|
||||
if (mWidget) {
|
||||
if (CompositorChild* remoteRenderer = mWidget->GetRemoteRenderer()) {
|
||||
nsIntRect bounds;
|
||||
mWidget->GetBounds(bounds);
|
||||
SurfaceDescriptor inSnapshot, snapshot;
|
||||
if (AllocSurfaceDescriptor(bounds.Size(),
|
||||
gfxASurface::CONTENT_COLOR_ALPHA,
|
||||
&inSnapshot) &&
|
||||
// The compositor will usually reuse |snapshot| and return
|
||||
// it through |outSnapshot|, but if it doesn't, it's
|
||||
// responsible for freeing |snapshot|.
|
||||
remoteRenderer->SendMakeSnapshot(inSnapshot, &snapshot)) {
|
||||
AutoOpenSurface opener(OPEN_READ_ONLY, snapshot);
|
||||
gfxASurface* source = opener.Get();
|
||||
|
||||
mShadowTarget->DrawSurface(source, source->GetSize());
|
||||
}
|
||||
if (IsSurfaceDescriptorValid(snapshot)) {
|
||||
ShadowLayerForwarder::DestroySharedSurface(&snapshot);
|
||||
}
|
||||
}
|
||||
}
|
||||
mShadowTarget = nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
ClientLayerManager::ForwardTransaction()
|
||||
{
|
||||
mPhase = PHASE_FORWARD;
|
||||
|
||||
// forward this transaction's changeset to our LayerManagerComposite
|
||||
AutoInfallibleTArray<EditReply, 10> replies;
|
||||
if (HasShadowManager() && ShadowLayerForwarder::EndTransaction(&replies)) {
|
||||
for (nsTArray<EditReply>::size_type i = 0; i < replies.Length(); ++i) {
|
||||
const EditReply& reply = replies[i];
|
||||
|
||||
switch (reply.type()) {
|
||||
case EditReply::TOpContentBufferSwap: {
|
||||
MOZ_LAYERS_LOG(("[LayersForwarder] DoubleBufferSwap"));
|
||||
|
||||
const OpContentBufferSwap& obs = reply.get_OpContentBufferSwap();
|
||||
|
||||
CompositableChild* compositableChild =
|
||||
static_cast<CompositableChild*>(obs.compositableChild());
|
||||
ContentClientRemote* contentClient =
|
||||
static_cast<ContentClientRemote*>(compositableChild->GetCompositableClient());
|
||||
MOZ_ASSERT(contentClient);
|
||||
|
||||
contentClient->SwapBuffers(obs.frontUpdatedRegion());
|
||||
|
||||
break;
|
||||
}
|
||||
case EditReply::TOpTextureSwap: {
|
||||
MOZ_LAYERS_LOG(("[LayersForwarder] TextureSwap"));
|
||||
|
||||
const OpTextureSwap& ots = reply.get_OpTextureSwap();
|
||||
|
||||
CompositableChild* compositableChild =
|
||||
static_cast<CompositableChild*>(ots.compositableChild());
|
||||
MOZ_ASSERT(compositableChild);
|
||||
|
||||
compositableChild->GetCompositableClient()
|
||||
->SetDescriptorFromReply(ots.textureId(), ots.image());
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
NS_RUNTIMEABORT("not reached");
|
||||
}
|
||||
}
|
||||
} else if (HasShadowManager()) {
|
||||
NS_WARNING("failed to forward Layers transaction");
|
||||
}
|
||||
|
||||
mPhase = PHASE_NONE;
|
||||
|
||||
// this may result in Layers being deleted, which results in
|
||||
// PLayer::Send__delete__() and DeallocShmem()
|
||||
mKeepAlive.Clear();
|
||||
}
|
||||
|
||||
ShadowableLayer*
|
||||
ClientLayerManager::Hold(Layer* aLayer)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(HasShadowManager(),
|
||||
"top-level tree, no shadow tree to remote to");
|
||||
|
||||
ShadowableLayer* shadowable = ClientLayer::ToClientLayer(aLayer);
|
||||
NS_ABORT_IF_FALSE(shadowable, "trying to remote an unshadowable layer");
|
||||
|
||||
mKeepAlive.AppendElement(aLayer);
|
||||
return shadowable;
|
||||
}
|
||||
|
||||
bool
|
||||
ClientLayerManager::IsCompositingCheap()
|
||||
{
|
||||
// Whether compositing is cheap depends on the parent backend.
|
||||
return mShadowManager &&
|
||||
LayerManager::IsCompositingCheap(GetCompositorBackendType());
|
||||
}
|
||||
|
||||
void
|
||||
ClientLayerManager::SetIsFirstPaint()
|
||||
{
|
||||
ShadowLayerForwarder::SetIsFirstPaint();
|
||||
}
|
||||
|
||||
void
|
||||
ClientLayerManager::ClearCachedResources(Layer* aSubtree)
|
||||
{
|
||||
MOZ_ASSERT(!HasShadowManager() || !aSubtree);
|
||||
if (PLayerTransactionChild* manager = GetShadowManager()) {
|
||||
manager->SendClearCachedResources();
|
||||
}
|
||||
if (aSubtree) {
|
||||
ClearLayer(aSubtree);
|
||||
} else if (mRoot) {
|
||||
ClearLayer(mRoot);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ClientLayerManager::ClearLayer(Layer* aLayer)
|
||||
{
|
||||
ClientLayer::ToClientLayer(aLayer)->ClearCachedResources();
|
||||
for (Layer* child = aLayer->GetFirstChild(); child;
|
||||
child = child->GetNextSibling()) {
|
||||
ClearLayer(child);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ClientLayerManager::GetBackendName(nsAString& aName)
|
||||
{
|
||||
switch (Compositor::GetBackend()) {
|
||||
case LAYERS_BASIC: aName.AssignLiteral("Basic"); return;
|
||||
case LAYERS_OPENGL: aName.AssignLiteral("OpenGL"); return;
|
||||
case LAYERS_D3D9: aName.AssignLiteral("Direct3D 9"); return;
|
||||
case LAYERS_D3D10: aName.AssignLiteral("Direct3D 10"); return;
|
||||
default: NS_RUNTIMEABORT("Invalid backend");
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
ClientLayerManager::ProgressiveUpdateCallback(bool aHasPendingNewThebesContent,
|
||||
gfx::Rect& aViewport,
|
||||
float& aScaleX,
|
||||
float& aScaleY,
|
||||
bool aDrawingCritical)
|
||||
{
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
Layer* primaryScrollable = GetPrimaryScrollableLayer();
|
||||
if (primaryScrollable) {
|
||||
const FrameMetrics& metrics = primaryScrollable->AsContainerLayer()->GetFrameMetrics();
|
||||
|
||||
// This is derived from the code in
|
||||
// gfx/layers/ipc/CompositorParent.cpp::TransformShadowTree.
|
||||
const gfx3DMatrix& rootTransform = GetRoot()->GetTransform();
|
||||
float devPixelRatioX = 1 / rootTransform.GetXScale();
|
||||
float devPixelRatioY = 1 / rootTransform.GetYScale();
|
||||
const gfx::Rect& metricsDisplayPort =
|
||||
(aDrawingCritical && !metrics.mCriticalDisplayPort.IsEmpty()) ?
|
||||
metrics.mCriticalDisplayPort : metrics.mDisplayPort;
|
||||
gfx::Rect displayPort((metricsDisplayPort.x + metrics.mScrollOffset.x) * devPixelRatioX,
|
||||
(metricsDisplayPort.y + metrics.mScrollOffset.y) * devPixelRatioY,
|
||||
metricsDisplayPort.width * devPixelRatioX,
|
||||
metricsDisplayPort.height * devPixelRatioY);
|
||||
|
||||
return AndroidBridge::Bridge()->ProgressiveUpdateCallback(
|
||||
aHasPendingNewThebesContent, displayPort, devPixelRatioX, aDrawingCritical,
|
||||
aViewport, aScaleX, aScaleY);
|
||||
}
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
ClientLayer::~ClientLayer()
|
||||
{
|
||||
if (HasShadow()) {
|
||||
PLayerChild::Send__delete__(GetShadow());
|
||||
}
|
||||
MOZ_COUNT_DTOR(ClientLayer);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
232
gfx/layers/client/ClientLayerManager.h
Normal file
232
gfx/layers/client/ClientLayerManager.h
Normal file
@ -0,0 +1,232 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* 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_CLIENTLAYERMANAGER_H
|
||||
#define GFX_CLIENTLAYERMANAGER_H
|
||||
|
||||
#include "Layers.h"
|
||||
#include "mozilla/layers/ShadowLayers.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
class ClientLayerManager : public LayerManager,
|
||||
public ShadowLayerForwarder
|
||||
{
|
||||
typedef nsTArray<nsRefPtr<Layer> > LayerRefArray;
|
||||
|
||||
public:
|
||||
ClientLayerManager(nsIWidget* aWidget);
|
||||
virtual ~ClientLayerManager();
|
||||
|
||||
virtual ShadowLayerForwarder* AsShadowForwarder()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
virtual int32_t GetMaxTextureSize() const;
|
||||
|
||||
virtual void SetDefaultTargetConfiguration(BufferMode aDoubleBuffering, ScreenRotation aRotation);
|
||||
virtual void BeginTransactionWithTarget(gfxContext* aTarget);
|
||||
virtual void BeginTransaction();
|
||||
virtual bool EndEmptyTransaction(EndTransactionFlags aFlags = END_DEFAULT);
|
||||
virtual void EndTransaction(DrawThebesLayerCallback aCallback,
|
||||
void* aCallbackData,
|
||||
EndTransactionFlags aFlags = END_DEFAULT);
|
||||
|
||||
virtual LayersBackend GetBackendType() { return LAYERS_CLIENT; }
|
||||
virtual void GetBackendName(nsAString& name);
|
||||
|
||||
virtual void SetRoot(Layer* aLayer);
|
||||
|
||||
virtual void Mutated(Layer* aLayer);
|
||||
|
||||
virtual already_AddRefed<ThebesLayer> CreateThebesLayer();
|
||||
virtual already_AddRefed<ContainerLayer> CreateContainerLayer();
|
||||
virtual already_AddRefed<ImageLayer> CreateImageLayer();
|
||||
virtual already_AddRefed<CanvasLayer> CreateCanvasLayer();
|
||||
virtual already_AddRefed<ColorLayer> CreateColorLayer();
|
||||
virtual already_AddRefed<RefLayer> CreateRefLayer();
|
||||
|
||||
ShadowableLayer* Hold(Layer* aLayer);
|
||||
|
||||
bool HasShadowManager() const { return ShadowLayerForwarder::HasShadowManager(); }
|
||||
|
||||
virtual bool IsCompositingCheap();
|
||||
virtual bool HasShadowManagerInternal() const { return HasShadowManager(); }
|
||||
|
||||
virtual void SetIsFirstPaint() MOZ_OVERRIDE;
|
||||
|
||||
// Drop cached resources and ask our shadow manager to do the same,
|
||||
// if we have one.
|
||||
virtual void ClearCachedResources(Layer* aSubtree = nullptr) MOZ_OVERRIDE;
|
||||
|
||||
void SetRepeatTransaction() { mRepeatTransaction = true; }
|
||||
bool GetRepeatTransaction() { return mRepeatTransaction; }
|
||||
|
||||
bool IsRepeatTransaction() { return mIsRepeatTransaction; }
|
||||
|
||||
void SetTransactionIncomplete() { mTransactionIncomplete = true; }
|
||||
|
||||
bool HasShadowTarget() { return !!mShadowTarget; }
|
||||
|
||||
bool CompositorMightResample() { return mCompositorMightResample; }
|
||||
|
||||
DrawThebesLayerCallback GetThebesLayerCallback() const
|
||||
{ return mThebesLayerCallback; }
|
||||
|
||||
void* GetThebesLayerCallbackData() const
|
||||
{ return mThebesLayerCallbackData; }
|
||||
|
||||
/**
|
||||
* Called for each iteration of a progressive tile update. Fills
|
||||
* aViewport, aScaleX and aScaleY with the current scale and viewport
|
||||
* being used to composite the layers in this manager, to determine what area
|
||||
* intersects with the target render rectangle. aDrawingCritical will be
|
||||
* true if the current drawing operation is using the critical displayport.
|
||||
* Returns true if the update should continue, or false if it should be
|
||||
* cancelled.
|
||||
* This is only called if gfxPlatform::UseProgressiveTilePainting() returns
|
||||
* true.
|
||||
*/
|
||||
bool ProgressiveUpdateCallback(bool aHasPendingNewThebesContent,
|
||||
gfx::Rect& aViewport,
|
||||
float& aScaleX,
|
||||
float& aScaleY,
|
||||
bool aDrawingCritical);
|
||||
|
||||
#ifdef DEBUG
|
||||
bool InConstruction() { return mPhase == PHASE_CONSTRUCTION; }
|
||||
bool InDrawing() { return mPhase == PHASE_DRAWING; }
|
||||
bool InForward() { return mPhase == PHASE_FORWARD; }
|
||||
#endif
|
||||
bool InTransaction() { return mPhase != PHASE_NONE; }
|
||||
|
||||
protected:
|
||||
enum TransactionPhase {
|
||||
PHASE_NONE, PHASE_CONSTRUCTION, PHASE_DRAWING, PHASE_FORWARD
|
||||
};
|
||||
TransactionPhase mPhase;
|
||||
|
||||
private:
|
||||
/**
|
||||
* Forward transaction results to the parent context.
|
||||
*/
|
||||
void ForwardTransaction();
|
||||
|
||||
/**
|
||||
* Take a snapshot of the parent context, and copy
|
||||
* it into mShadowTarget.
|
||||
*/
|
||||
void MakeSnapshotIfRequired();
|
||||
|
||||
void ClearLayer(Layer* aLayer);
|
||||
|
||||
bool EndTransactionInternal(DrawThebesLayerCallback aCallback,
|
||||
void* aCallbackData,
|
||||
EndTransactionFlags);
|
||||
|
||||
// The bounds of |mTarget| in device pixels.
|
||||
nsIntRect mTargetBounds;
|
||||
|
||||
LayerRefArray mKeepAlive;
|
||||
|
||||
nsIWidget* mWidget;
|
||||
|
||||
/* Thebes layer callbacks; valid at the end of a transaciton,
|
||||
* while rendering */
|
||||
DrawThebesLayerCallback mThebesLayerCallback;
|
||||
void *mThebesLayerCallbackData;
|
||||
|
||||
// When we're doing a transaction in order to draw to a non-default
|
||||
// target, the layers transaction is only performed in order to send
|
||||
// a PLayers:Update. We save the original non-default target to
|
||||
// mShadowTarget, and then perform the transaction using
|
||||
// mDummyTarget as the render target. After the transaction ends,
|
||||
// we send a message to our remote side to capture the actual pixels
|
||||
// being drawn to the default target, and then copy those pixels
|
||||
// back to mShadowTarget.
|
||||
nsRefPtr<gfxContext> mShadowTarget;
|
||||
|
||||
// Sometimes we draw to targets that don't natively support
|
||||
// landscape/portrait orientation. When we need to implement that
|
||||
// ourselves, |mTargetRotation| describes the induced transform we
|
||||
// need to apply when compositing content to our target.
|
||||
ScreenRotation mTargetRotation;
|
||||
|
||||
// Used to repeat the transaction right away (to avoid rebuilding
|
||||
// a display list) to support progressive drawing.
|
||||
bool mRepeatTransaction;
|
||||
bool mIsRepeatTransaction;
|
||||
bool mTransactionIncomplete;
|
||||
bool mCompositorMightResample;
|
||||
};
|
||||
|
||||
class ClientThebesLayer;
|
||||
class ClientLayer : public ShadowableLayer
|
||||
{
|
||||
public:
|
||||
ClientLayer()
|
||||
{
|
||||
MOZ_COUNT_CTOR(ClientLayer);
|
||||
}
|
||||
|
||||
~ClientLayer();
|
||||
|
||||
void SetShadow(PLayerChild* aShadow)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(!mShadow, "can't have two shadows (yet)");
|
||||
mShadow = aShadow;
|
||||
}
|
||||
|
||||
virtual void Disconnect()
|
||||
{
|
||||
// This is an "emergency Disconnect()", called when the compositing
|
||||
// process has died. |mShadow| and our Shmem buffers are
|
||||
// automatically managed by IPDL, so we don't need to explicitly
|
||||
// free them here (it's hard to get that right on emergency
|
||||
// shutdown anyway).
|
||||
mShadow = nullptr;
|
||||
}
|
||||
|
||||
virtual void ClearCachedResources() { }
|
||||
|
||||
virtual void RenderLayer() = 0;
|
||||
|
||||
virtual ClientThebesLayer* AsThebes() { return nullptr; }
|
||||
|
||||
static inline ClientLayer *
|
||||
ToClientLayer(Layer* aLayer)
|
||||
{
|
||||
return static_cast<ClientLayer*>(aLayer->ImplData());
|
||||
}
|
||||
};
|
||||
|
||||
// Create a shadow layer (PLayerChild) for aLayer, if we're forwarding
|
||||
// our layer tree to a parent process. Record the new layer creation
|
||||
// in the current open transaction as a side effect.
|
||||
template<typename CreatedMethod> void
|
||||
CreateShadowFor(ClientLayer* aLayer,
|
||||
ClientLayerManager* aMgr,
|
||||
CreatedMethod aMethod)
|
||||
{
|
||||
PLayerChild* shadow = aMgr->ConstructShadowFor(aLayer);
|
||||
// XXX error handling
|
||||
NS_ABORT_IF_FALSE(shadow, "failed to create shadow");
|
||||
|
||||
aLayer->SetShadow(shadow);
|
||||
(aMgr->*aMethod)(aLayer);
|
||||
aMgr->Hold(aLayer->AsLayer());
|
||||
}
|
||||
|
||||
#define CREATE_SHADOW(_type) \
|
||||
CreateShadowFor(layer, this, \
|
||||
&ShadowLayerForwarder::Created ## _type ## Layer)
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* GFX_CLIENTLAYERMANAGER_H */
|
190
gfx/layers/client/ClientThebesLayer.cpp
Normal file
190
gfx/layers/client/ClientThebesLayer.cpp
Normal file
@ -0,0 +1,190 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* 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 "ClientThebesLayer.h"
|
||||
#include "ClientTiledThebesLayer.h"
|
||||
|
||||
using namespace mozilla::gfx;
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
static void
|
||||
SetAntialiasingFlags(Layer* aLayer, gfxContext* aTarget)
|
||||
{
|
||||
if (!aTarget->IsCairo()) {
|
||||
RefPtr<DrawTarget> dt = aTarget->GetDrawTarget();
|
||||
|
||||
if (dt->GetFormat() != FORMAT_B8G8R8A8) {
|
||||
return;
|
||||
}
|
||||
|
||||
const nsIntRect& bounds = aLayer->GetVisibleRegion().GetBounds();
|
||||
gfx::Rect transformedBounds = dt->GetTransform().TransformBounds(gfx::Rect(Float(bounds.x), Float(bounds.y),
|
||||
Float(bounds.width), Float(bounds.height)));
|
||||
transformedBounds.RoundOut();
|
||||
IntRect intTransformedBounds;
|
||||
transformedBounds.ToIntRect(&intTransformedBounds);
|
||||
dt->SetPermitSubpixelAA(!(aLayer->GetContentFlags() & Layer::CONTENT_COMPONENT_ALPHA) ||
|
||||
dt->GetOpaqueRect().Contains(intTransformedBounds));
|
||||
} else {
|
||||
nsRefPtr<gfxASurface> surface = aTarget->CurrentSurface();
|
||||
if (surface->GetContentType() != gfxASurface::CONTENT_COLOR_ALPHA) {
|
||||
// Destination doesn't have alpha channel; no need to set any special flags
|
||||
return;
|
||||
}
|
||||
|
||||
const nsIntRect& bounds = aLayer->GetVisibleRegion().GetBounds();
|
||||
surface->SetSubpixelAntialiasingEnabled(
|
||||
!(aLayer->GetContentFlags() & Layer::CONTENT_COMPONENT_ALPHA) ||
|
||||
surface->GetOpaqueRect().Contains(
|
||||
aTarget->UserToDevice(gfxRect(bounds.x, bounds.y, bounds.width, bounds.height))));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ClientThebesLayer::PaintThebes()
|
||||
{
|
||||
PROFILER_LABEL("ClientThebesLayer", "PaintThebes");
|
||||
NS_ASSERTION(ClientManager()->InDrawing(),
|
||||
"Can only draw in drawing phase");
|
||||
|
||||
//TODO: This is going to copy back pixels that we might end up
|
||||
// drawing over anyway. It would be nice if we could avoid
|
||||
// this duplication.
|
||||
mContentClient->SyncFrontBufferToBackBuffer();
|
||||
|
||||
bool canUseOpaqueSurface = CanUseOpaqueSurface();
|
||||
ContentType contentType =
|
||||
canUseOpaqueSurface ? gfxASurface::CONTENT_COLOR :
|
||||
gfxASurface::CONTENT_COLOR_ALPHA;
|
||||
|
||||
{
|
||||
uint32_t flags = 0;
|
||||
#ifndef MOZ_WIDGET_ANDROID
|
||||
if (ClientManager()->CompositorMightResample()) {
|
||||
flags |= ThebesLayerBuffer::PAINT_WILL_RESAMPLE;
|
||||
}
|
||||
if (!(flags & ThebesLayerBuffer::PAINT_WILL_RESAMPLE)) {
|
||||
if (MayResample()) {
|
||||
flags |= ThebesLayerBuffer::PAINT_WILL_RESAMPLE;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
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);
|
||||
|
||||
PaintBuffer(state.mContext,
|
||||
state.mRegionToDraw, extendedDrawRegion, state.mRegionToInvalidate,
|
||||
state.mDidSelfCopy);
|
||||
MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) PaintThebes", this));
|
||||
Mutated();
|
||||
} 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?");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ClientThebesLayer::RenderLayer()
|
||||
{
|
||||
if (GetMaskLayer()) {
|
||||
ToClientLayer(GetMaskLayer())->RenderLayer();
|
||||
}
|
||||
|
||||
if (!mContentClient) {
|
||||
mContentClient = ContentClient::CreateContentClient(ClientManager());
|
||||
if (!mContentClient) {
|
||||
return;
|
||||
}
|
||||
mContentClient->Connect();
|
||||
ClientManager()->Attach(mContentClient, this);
|
||||
MOZ_ASSERT(mContentClient->GetForwarder());
|
||||
}
|
||||
|
||||
mContentClient->BeginPaint();
|
||||
PaintThebes();
|
||||
mContentClient->EndPaint();
|
||||
}
|
||||
|
||||
void
|
||||
ClientThebesLayer::PaintBuffer(gfxContext* aContext,
|
||||
const nsIntRegion& aRegionToDraw,
|
||||
const nsIntRegion& aExtendedRegionToDraw,
|
||||
const nsIntRegion& aRegionToInvalidate,
|
||||
bool aDidSelfCopy)
|
||||
{
|
||||
ContentClientRemote* contentClientRemote = static_cast<ContentClientRemote*>(mContentClient.get());
|
||||
MOZ_ASSERT(contentClientRemote->GetIPDLActor());
|
||||
|
||||
// NB: this just throws away the entire valid region if there are
|
||||
// too many rects.
|
||||
mValidRegion.SimplifyInward(8);
|
||||
|
||||
if (!ClientManager()->GetThebesLayerCallback()) {
|
||||
ClientManager()->SetTransactionIncomplete();
|
||||
return;
|
||||
}
|
||||
ClientManager()->GetThebesLayerCallback()(this,
|
||||
aContext,
|
||||
aExtendedRegionToDraw,
|
||||
aRegionToInvalidate,
|
||||
ClientManager()->GetThebesLayerCallbackData());
|
||||
|
||||
// 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, aExtendedRegionToDraw);
|
||||
mValidRegion.Or(mValidRegion, tmp);
|
||||
|
||||
// Hold(this) ensures this layer is kept alive through the current transaction
|
||||
// The ContentClient assumes this layer is kept alive (e.g., in CreateBuffer,
|
||||
// DestroyThebesBuffer), so deleting this Hold for whatever reason will break things.
|
||||
ClientManager()->Hold(this);
|
||||
contentClientRemote->Updated(aRegionToDraw,
|
||||
mVisibleRegion,
|
||||
aDidSelfCopy);
|
||||
}
|
||||
|
||||
already_AddRefed<ThebesLayer>
|
||||
ClientLayerManager::CreateThebesLayer()
|
||||
{
|
||||
NS_ASSERTION(InConstruction(), "Only allowed in construction phase");
|
||||
#ifdef FORCE_BASICTILEDTHEBESLAYER
|
||||
if (GetCompositorBackendType() == LAYERS_OPENGL) {
|
||||
nsRefPtr<ClientTiledThebesLayer> layer =
|
||||
new ClientTiledThebesLayer(this);
|
||||
CREATE_SHADOW(Thebes);
|
||||
return layer.forget();
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
nsRefPtr<ClientThebesLayer> layer =
|
||||
new ClientThebesLayer(this);
|
||||
CREATE_SHADOW(Thebes);
|
||||
return layer.forget();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
104
gfx/layers/client/ClientThebesLayer.h
Normal file
104
gfx/layers/client/ClientThebesLayer.h
Normal file
@ -0,0 +1,104 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* 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_CLIENTTHEBESLAYER_H
|
||||
#define GFX_CLIENTTHEBESLAYER_H
|
||||
|
||||
#include "ClientLayerManager.h"
|
||||
#include "ThebesLayerBuffer.h"
|
||||
#include "mozilla/layers/ContentClient.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
class ClientThebesLayer : public ThebesLayer,
|
||||
public ClientLayer {
|
||||
public:
|
||||
typedef ThebesLayerBuffer::PaintState PaintState;
|
||||
typedef ThebesLayerBuffer::ContentType ContentType;
|
||||
|
||||
ClientThebesLayer(ClientLayerManager* aLayerManager) :
|
||||
ThebesLayer(aLayerManager, static_cast<ClientLayer*>(this)),
|
||||
mContentClient(nullptr)
|
||||
{
|
||||
MOZ_COUNT_CTOR(ClientThebesLayer);
|
||||
}
|
||||
virtual ~ClientThebesLayer()
|
||||
{
|
||||
MOZ_COUNT_DTOR(ClientThebesLayer);
|
||||
}
|
||||
|
||||
virtual void SetVisibleRegion(const nsIntRegion& aRegion)
|
||||
{
|
||||
NS_ASSERTION(ClientManager()->InConstruction(),
|
||||
"Can only set properties in construction phase");
|
||||
ThebesLayer::SetVisibleRegion(aRegion);
|
||||
}
|
||||
virtual void InvalidateRegion(const nsIntRegion& aRegion)
|
||||
{
|
||||
NS_ASSERTION(ClientManager()->InConstruction(),
|
||||
"Can only set properties in construction phase");
|
||||
mInvalidRegion.Or(mInvalidRegion, aRegion);
|
||||
mInvalidRegion.SimplifyOutward(10);
|
||||
mValidRegion.Sub(mValidRegion, mInvalidRegion);
|
||||
}
|
||||
|
||||
virtual void RenderLayer();
|
||||
|
||||
virtual void ClearCachedResources()
|
||||
{
|
||||
if (mContentClient) {
|
||||
mContentClient->Clear();
|
||||
}
|
||||
mValidRegion.SetEmpty();
|
||||
DestroyBackBuffer();
|
||||
}
|
||||
|
||||
virtual void FillSpecificAttributes(SpecificLayerAttributes& aAttrs)
|
||||
{
|
||||
aAttrs = ThebesLayerAttributes(GetValidRegion());
|
||||
}
|
||||
|
||||
ClientLayerManager* ClientManager()
|
||||
{
|
||||
return static_cast<ClientLayerManager*>(mManager);
|
||||
}
|
||||
|
||||
virtual Layer* AsLayer() { return this; }
|
||||
virtual ShadowableLayer* AsShadowableLayer() { return this; }
|
||||
|
||||
virtual CompositableClient* GetCompositableClient() MOZ_OVERRIDE
|
||||
{
|
||||
return mContentClient;
|
||||
}
|
||||
|
||||
virtual void Disconnect()
|
||||
{
|
||||
mContentClient = nullptr;
|
||||
ClientLayer::Disconnect();
|
||||
}
|
||||
|
||||
protected:
|
||||
void
|
||||
PaintBuffer(gfxContext* aContext,
|
||||
const nsIntRegion& aRegionToDraw,
|
||||
const nsIntRegion& aExtendedRegionToDraw,
|
||||
const nsIntRegion& aRegionToInvalidate,
|
||||
bool aDidSelfCopy);
|
||||
|
||||
void PaintThebes();
|
||||
|
||||
void DestroyBackBuffer()
|
||||
{
|
||||
mContentClient = nullptr;
|
||||
}
|
||||
|
||||
RefPtr<ContentClient> mContentClient;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -3,7 +3,7 @@
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "mozilla/layers/PLayerTransactionChild.h"
|
||||
#include "BasicTiledThebesLayer.h"
|
||||
#include "ClientTiledThebesLayer.h"
|
||||
#include "gfxImageSurface.h"
|
||||
#include "GeckoProfiler.h"
|
||||
#include "gfxPlatform.h"
|
||||
@ -13,30 +13,30 @@ namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
|
||||
BasicTiledThebesLayer::BasicTiledThebesLayer(BasicShadowLayerManager* const aManager)
|
||||
: ThebesLayer(aManager, static_cast<BasicImplData*>(this))
|
||||
ClientTiledThebesLayer::ClientTiledThebesLayer(ClientLayerManager* const aManager)
|
||||
: ThebesLayer(aManager, static_cast<ClientLayer*>(this))
|
||||
, mContentClient()
|
||||
{
|
||||
MOZ_COUNT_CTOR(BasicTiledThebesLayer);
|
||||
MOZ_COUNT_CTOR(ClientTiledThebesLayer);
|
||||
mPaintData.mLastScrollOffset = gfx::Point(0, 0);
|
||||
mPaintData.mFirstPaint = true;
|
||||
}
|
||||
|
||||
BasicTiledThebesLayer::~BasicTiledThebesLayer()
|
||||
ClientTiledThebesLayer::~ClientTiledThebesLayer()
|
||||
{
|
||||
MOZ_COUNT_DTOR(BasicTiledThebesLayer);
|
||||
MOZ_COUNT_DTOR(ClientTiledThebesLayer);
|
||||
}
|
||||
|
||||
void
|
||||
BasicTiledThebesLayer::FillSpecificAttributes(SpecificLayerAttributes& aAttrs)
|
||||
ClientTiledThebesLayer::FillSpecificAttributes(SpecificLayerAttributes& aAttrs)
|
||||
{
|
||||
aAttrs = ThebesLayerAttributes(GetValidRegion());
|
||||
}
|
||||
|
||||
void
|
||||
BasicTiledThebesLayer::BeginPaint()
|
||||
ClientTiledThebesLayer::BeginPaint()
|
||||
{
|
||||
if (BasicManager()->IsRepeatTransaction()) {
|
||||
if (ClientManager()->IsRepeatTransaction()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -82,7 +82,7 @@ BasicTiledThebesLayer::BeginPaint()
|
||||
// composition bounds.
|
||||
mPaintData.mCompositionBounds.SetEmpty();
|
||||
mPaintData.mScrollOffset.MoveTo(0, 0);
|
||||
Layer* primaryScrollable = BasicManager()->GetPrimaryScrollableLayer();
|
||||
Layer* primaryScrollable = ClientManager()->GetPrimaryScrollableLayer();
|
||||
if (primaryScrollable) {
|
||||
const FrameMetrics& metrics = primaryScrollable->AsContainerLayer()->GetFrameMetrics();
|
||||
mPaintData.mScrollOffset = metrics.mScrollOffset;
|
||||
@ -97,7 +97,7 @@ BasicTiledThebesLayer::BeginPaint()
|
||||
}
|
||||
|
||||
void
|
||||
BasicTiledThebesLayer::EndPaint(bool aFinish)
|
||||
ClientTiledThebesLayer::EndPaint(bool aFinish)
|
||||
{
|
||||
if (!aFinish && !mPaintData.mPaintFinished) {
|
||||
return;
|
||||
@ -108,27 +108,21 @@ BasicTiledThebesLayer::EndPaint(bool aFinish)
|
||||
}
|
||||
|
||||
void
|
||||
BasicTiledThebesLayer::PaintThebes(gfxContext* aContext,
|
||||
Layer* aMaskLayer,
|
||||
LayerManager::DrawThebesLayerCallback aCallback,
|
||||
void* aCallbackData,
|
||||
ReadbackProcessor* aReadback)
|
||||
ClientTiledThebesLayer::RenderLayer()
|
||||
{
|
||||
if (!HasShadow()) {
|
||||
NS_ASSERTION(false, "Shadow requested for painting\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!aCallback) {
|
||||
BasicManager()->SetTransactionIncomplete();
|
||||
LayerManager::DrawThebesLayerCallback callback =
|
||||
ClientManager()->GetThebesLayerCallback();
|
||||
void *data = ClientManager()->GetThebesLayerCallbackData();
|
||||
if (!callback) {
|
||||
ClientManager()->SetTransactionIncomplete();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mContentClient) {
|
||||
mContentClient = new TiledContentClient(this, BasicManager());
|
||||
mContentClient = new TiledContentClient(this, ClientManager());
|
||||
|
||||
mContentClient->Connect();
|
||||
BasicManager()->Attach(mContentClient, this);
|
||||
ClientManager()->Attach(mContentClient, this);
|
||||
MOZ_ASSERT(mContentClient->GetForwarder());
|
||||
}
|
||||
|
||||
@ -144,8 +138,8 @@ BasicTiledThebesLayer::PaintThebes(gfxContext* aContext,
|
||||
}
|
||||
|
||||
// Only paint the mask layer on the first transaction.
|
||||
if (aMaskLayer && !BasicManager()->IsRepeatTransaction()) {
|
||||
static_cast<BasicImplData*>(aMaskLayer->ImplData())->Paint(aContext, nullptr);
|
||||
if (GetMaskLayer() && !ClientManager()->IsRepeatTransaction()) {
|
||||
ToClientLayer(GetMaskLayer())->RenderLayer();
|
||||
}
|
||||
|
||||
// Fast path for no progressive updates, no low-precision updates and no
|
||||
@ -155,12 +149,12 @@ BasicTiledThebesLayer::PaintThebes(gfxContext* aContext,
|
||||
GetParent()->GetFrameMetrics().mCriticalDisplayPort.IsEmpty()) {
|
||||
mValidRegion = mVisibleRegion;
|
||||
|
||||
NS_ASSERTION(!BasicManager()->IsRepeatTransaction(), "Didn't paint our mask layer");
|
||||
NS_ASSERTION(!ClientManager()->IsRepeatTransaction(), "Didn't paint our mask layer");
|
||||
|
||||
mContentClient->mTiledBuffer.PaintThebes(mValidRegion, invalidRegion,
|
||||
aCallback, aCallbackData);
|
||||
callback, data);
|
||||
|
||||
BasicManager()->Hold(this);
|
||||
ClientManager()->Hold(this);
|
||||
mContentClient->LockCopyAndWrite(TiledContentClient::TILED_BUFFER);
|
||||
|
||||
return;
|
||||
@ -174,7 +168,7 @@ BasicTiledThebesLayer::PaintThebes(gfxContext* aContext,
|
||||
|
||||
// Make sure that tiles that fall outside of the visible region are
|
||||
// discarded on the first update.
|
||||
if (!BasicManager()->IsRepeatTransaction()) {
|
||||
if (!ClientManager()->IsRepeatTransaction()) {
|
||||
mValidRegion.And(mValidRegion, mVisibleRegion);
|
||||
if (!mPaintData.mLayerCriticalDisplayPort.IsEmpty()) {
|
||||
// Make sure that tiles that fall outside of the critical displayport are
|
||||
@ -206,7 +200,7 @@ BasicTiledThebesLayer::PaintThebes(gfxContext* aContext,
|
||||
bool updatedBuffer = false;
|
||||
// Only draw progressively when the resolution is unchanged.
|
||||
if (gfxPlatform::UseProgressiveTilePainting() &&
|
||||
!BasicManager()->HasShadowTarget() &&
|
||||
!ClientManager()->HasShadowTarget() &&
|
||||
mContentClient->mTiledBuffer.GetFrameResolution() == mPaintData.mResolution) {
|
||||
// Store the old valid region, then clear it before painting.
|
||||
// We clip the old valid region to the visible region, as it only gets
|
||||
@ -220,7 +214,7 @@ BasicTiledThebesLayer::PaintThebes(gfxContext* aContext,
|
||||
updatedBuffer =
|
||||
mContentClient->mTiledBuffer.ProgressiveUpdate(mValidRegion, invalidRegion,
|
||||
oldValidRegion, &mPaintData,
|
||||
aCallback, aCallbackData);
|
||||
callback, data);
|
||||
} else {
|
||||
updatedBuffer = true;
|
||||
mValidRegion = mVisibleRegion;
|
||||
@ -229,18 +223,18 @@ BasicTiledThebesLayer::PaintThebes(gfxContext* aContext,
|
||||
}
|
||||
mContentClient->mTiledBuffer.SetFrameResolution(mPaintData.mResolution);
|
||||
mContentClient->mTiledBuffer.PaintThebes(mValidRegion, invalidRegion,
|
||||
aCallback, aCallbackData);
|
||||
callback, data);
|
||||
}
|
||||
|
||||
if (updatedBuffer) {
|
||||
mPaintData.mFirstPaint = false;
|
||||
BasicManager()->Hold(this);
|
||||
ClientManager()->Hold(this);
|
||||
mContentClient->LockCopyAndWrite(TiledContentClient::TILED_BUFFER);
|
||||
|
||||
// If there are low precision updates, mark the paint as unfinished and
|
||||
// request a repeat transaction.
|
||||
if (!lowPrecisionInvalidRegion.IsEmpty() && mPaintData.mPaintFinished) {
|
||||
BasicManager()->SetRepeatTransaction();
|
||||
ClientManager()->SetRepeatTransaction();
|
||||
mPaintData.mLowPrecisionPaintCount = 1;
|
||||
mPaintData.mPaintFinished = false;
|
||||
}
|
||||
@ -288,7 +282,7 @@ BasicTiledThebesLayer::PaintThebes(gfxContext* aContext,
|
||||
.ProgressiveUpdate(mLowPrecisionValidRegion,
|
||||
lowPrecisionInvalidRegion,
|
||||
oldValidRegion, &mPaintData,
|
||||
aCallback, aCallbackData);
|
||||
callback, data);
|
||||
}
|
||||
} else if (!mLowPrecisionValidRegion.IsEmpty()) {
|
||||
// Clear the low precision tiled buffer
|
||||
@ -296,14 +290,14 @@ BasicTiledThebesLayer::PaintThebes(gfxContext* aContext,
|
||||
mLowPrecisionValidRegion.SetEmpty();
|
||||
mContentClient->mLowPrecisionTiledBuffer.PaintThebes(mLowPrecisionValidRegion,
|
||||
mLowPrecisionValidRegion,
|
||||
aCallback, aCallbackData);
|
||||
callback, data);
|
||||
}
|
||||
|
||||
// We send a Painted callback if we clear the valid region of the low
|
||||
// precision buffer, so that the shadow buffer's valid region can be updated
|
||||
// and the associated resources can be freed.
|
||||
if (updatedLowPrecision) {
|
||||
BasicManager()->Hold(this);
|
||||
ClientManager()->Hold(this);
|
||||
mContentClient->LockCopyAndWrite(TiledContentClient::LOW_PRECISION_TILED_BUFFER);
|
||||
}
|
||||
|
@ -2,12 +2,11 @@
|
||||
* 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_BASICTILEDTHEBESLAYER_H
|
||||
#define GFX_BASICTILEDTHEBESLAYER_H
|
||||
#ifndef GFX_CLIENTTILEDTHEBESLAYER_H
|
||||
#define GFX_CLIENTTILEDTHEBESLAYER_H
|
||||
|
||||
#include "mozilla/layers/ShadowLayers.h"
|
||||
#include "BasicLayers.h"
|
||||
#include "BasicImplData.h"
|
||||
#include "ClientLayerManager.h"
|
||||
#include "mozilla/layers/TiledContentClient.h" // tiles and tile buffer
|
||||
|
||||
namespace mozilla {
|
||||
@ -30,15 +29,14 @@ class BasicTiledLayerBuffer;
|
||||
*
|
||||
* There is no ContentClient for tiled layers. There is a ContentHost, however.
|
||||
*/
|
||||
class BasicTiledThebesLayer : public ThebesLayer,
|
||||
public BasicImplData,
|
||||
public BasicShadowableLayer
|
||||
class ClientTiledThebesLayer : public ThebesLayer,
|
||||
public ClientLayer
|
||||
{
|
||||
typedef ThebesLayer Base;
|
||||
|
||||
public:
|
||||
BasicTiledThebesLayer(BasicShadowLayerManager* const aManager);
|
||||
~BasicTiledThebesLayer();
|
||||
ClientTiledThebesLayer(ClientLayerManager* const aManager);
|
||||
~ClientTiledThebesLayer();
|
||||
|
||||
// Thebes Layer
|
||||
virtual Layer* AsLayer() { return this; }
|
||||
@ -54,19 +52,15 @@ public:
|
||||
|
||||
virtual void Disconnect()
|
||||
{
|
||||
BasicShadowableLayer::Disconnect();
|
||||
ClientLayer::Disconnect();
|
||||
}
|
||||
|
||||
virtual void PaintThebes(gfxContext* aContext,
|
||||
Layer* aMaskLayer,
|
||||
LayerManager::DrawThebesLayerCallback aCallback,
|
||||
void* aCallbackData,
|
||||
ReadbackProcessor* aReadback);
|
||||
virtual void RenderLayer();
|
||||
|
||||
private:
|
||||
BasicShadowLayerManager* BasicManager()
|
||||
ClientLayerManager* ClientManager()
|
||||
{
|
||||
return static_cast<BasicShadowLayerManager*>(mManager);
|
||||
return static_cast<ClientLayerManager*>(mManager);
|
||||
}
|
||||
|
||||
// BasicImplData
|
@ -6,7 +6,7 @@
|
||||
#include "mozilla/layers/TiledContentClient.h"
|
||||
#include "mozilla/gfx/2D.h"
|
||||
#include "mozilla/MathAlgorithms.h"
|
||||
#include "BasicTiledThebesLayer.h"
|
||||
#include "ClientTiledThebesLayer.h"
|
||||
|
||||
#ifdef GFX_TILEDLAYER_DEBUG_OVERLAY
|
||||
#include "cairo.h"
|
||||
@ -59,8 +59,8 @@ using namespace gfx;
|
||||
namespace layers {
|
||||
|
||||
|
||||
TiledContentClient::TiledContentClient(BasicTiledThebesLayer* aThebesLayer,
|
||||
BasicShadowLayerManager* aManager)
|
||||
TiledContentClient::TiledContentClient(ClientTiledThebesLayer* aThebesLayer,
|
||||
ClientLayerManager* aManager)
|
||||
: CompositableClient(aManager->AsShadowForwarder())
|
||||
, mTiledBuffer(aThebesLayer, aManager)
|
||||
, mLowPrecisionTiledBuffer(aThebesLayer, aManager)
|
||||
@ -87,8 +87,8 @@ TiledContentClient::LockCopyAndWrite(TiledBufferType aType)
|
||||
buffer->ClearPaintedRegion();
|
||||
}
|
||||
|
||||
BasicTiledLayerBuffer::BasicTiledLayerBuffer(BasicTiledThebesLayer* aThebesLayer,
|
||||
BasicShadowLayerManager* aManager)
|
||||
BasicTiledLayerBuffer::BasicTiledLayerBuffer(ClientTiledThebesLayer* aThebesLayer,
|
||||
ClientLayerManager* aManager)
|
||||
: mThebesLayer(aThebesLayer)
|
||||
, mManager(aManager)
|
||||
, mLastPaintOpaque(false)
|
||||
|
@ -84,8 +84,8 @@ struct BasicTiledLayerPaintData {
|
||||
bool mPaintFinished : 1;
|
||||
};
|
||||
|
||||
class BasicTiledThebesLayer;
|
||||
class BasicShadowLayerManager;
|
||||
class ClientTiledThebesLayer;
|
||||
class ClientLayerManager;
|
||||
|
||||
/**
|
||||
* Provide an instance of TiledLayerBuffer backed by image surfaces.
|
||||
@ -99,8 +99,8 @@ class BasicTiledLayerBuffer
|
||||
friend class TiledLayerBuffer<BasicTiledLayerBuffer, BasicTiledLayerTile>;
|
||||
|
||||
public:
|
||||
BasicTiledLayerBuffer(BasicTiledThebesLayer* aThebesLayer,
|
||||
BasicShadowLayerManager* aManager);
|
||||
BasicTiledLayerBuffer(ClientTiledThebesLayer* aThebesLayer,
|
||||
ClientLayerManager* aManager);
|
||||
BasicTiledLayerBuffer()
|
||||
: mThebesLayer(nullptr)
|
||||
, mManager(nullptr)
|
||||
@ -172,8 +172,8 @@ protected:
|
||||
|
||||
private:
|
||||
gfxASurface::gfxContentType GetContentType() const;
|
||||
BasicTiledThebesLayer* mThebesLayer;
|
||||
BasicShadowLayerManager* mManager;
|
||||
ClientTiledThebesLayer* mThebesLayer;
|
||||
ClientLayerManager* mManager;
|
||||
LayerManager::DrawThebesLayerCallback mCallback;
|
||||
void* mCallbackData;
|
||||
gfxSize mFrameResolution;
|
||||
@ -221,11 +221,11 @@ class TiledContentClient : public CompositableClient
|
||||
// We should have a content client for each tiled buffer which manages its
|
||||
// own valid region, resolution, etc. Then we could have a much cleaner
|
||||
// interface and tidy up BasicTiledThebesLayer::PaintThebes (bug 862547).
|
||||
friend class BasicTiledThebesLayer;
|
||||
friend class ClientTiledThebesLayer;
|
||||
|
||||
public:
|
||||
TiledContentClient(BasicTiledThebesLayer* aThebesLayer,
|
||||
BasicShadowLayerManager* aManager);
|
||||
TiledContentClient(ClientTiledThebesLayer* aThebesLayer,
|
||||
ClientLayerManager* aManager);
|
||||
|
||||
~TiledContentClient()
|
||||
{
|
||||
|
@ -10,7 +10,7 @@
|
||||
#include "mozilla/layers/PCompositableParent.h"
|
||||
#include "mozilla/layers/ISurfaceAllocator.h"
|
||||
#include "ThebesLayerBuffer.h"
|
||||
#include "BasicTiledThebesLayer.h" // for BasicTiledLayerBuffer
|
||||
#include "ClientTiledThebesLayer.h" // for BasicTiledLayerBuffer
|
||||
#include "mozilla/RefPtr.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
@ -7,7 +7,7 @@
|
||||
#define GFX_TILEDCONTENTHOST_H
|
||||
|
||||
#include "ContentHost.h"
|
||||
#include "BasicTiledThebesLayer.h" // for BasicTiledLayerBuffer
|
||||
#include "ClientTiledThebesLayer.h" // for BasicTiledLayerBuffer
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
@ -11,9 +11,14 @@ EXPORTS += [
|
||||
'BasicImplData.h',
|
||||
'BasicLayers.h',
|
||||
'BasicLayersImpl.h',
|
||||
'BasicTiledThebesLayer.h',
|
||||
'BasicThebesLayer.h',
|
||||
'CompositableHost.h',
|
||||
'CopyableCanvasLayer.h',
|
||||
'ClientLayerManager.h',
|
||||
'ClientContainerLayer.h',
|
||||
'ClientThebesLayer.h',
|
||||
'ClientTiledThebesLayer.h',
|
||||
'ClientCanvasLayer.h',
|
||||
'Composer2D.h',
|
||||
'GonkIOSurfaceImage.h',
|
||||
'FrameMetrics.h',
|
||||
|
@ -26,6 +26,7 @@ var Cc = SpecialPowers.Cc;
|
||||
var Ci = SpecialPowers.Ci;
|
||||
|
||||
var sysInfo = Cc["@mozilla.org/system-info;1"].getService(Ci.nsIPropertyBag2);
|
||||
var xr = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime);
|
||||
|
||||
var windows = SpecialPowers.Services.ww.getWindowEnumerator();
|
||||
var windowutils;
|
||||
@ -93,7 +94,11 @@ switch(osName)
|
||||
break;
|
||||
|
||||
default: // Linux and others.
|
||||
is(acceleratedWindows, 0, "Acceleration not supported on '" + osName + "'");
|
||||
if (xr.OS == "Android" && xr.widgetToolkit != "gonk") {
|
||||
isnot(acceleratedWindows, 0, "Acceleration enabled on Android");
|
||||
} else {
|
||||
is(acceleratedWindows, 0, "Acceleration not supported on '" + osName + "'");
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
@ -2830,7 +2830,7 @@ NSEvent* gLastDragMouseDownEvent = nil;
|
||||
|
||||
nsAutoRetainCocoaObject kungFuDeathGrip(self);
|
||||
bool painted;
|
||||
{
|
||||
if (mGeckoChild->GetLayerManager()->GetBackendType() == LAYERS_BASIC) {
|
||||
nsBaseWidget::AutoLayerManagerSetup
|
||||
setupLayerManager(mGeckoChild, targetContext, BUFFER_NONE);
|
||||
painted = mGeckoChild->PaintWindow(region, aIsAlternate);
|
||||
|
@ -43,6 +43,7 @@
|
||||
#include "nsWindow.h"
|
||||
#include "nsIWidgetListener.h"
|
||||
#include "cutils/properties.h"
|
||||
#include "ClientLayerManager.h"
|
||||
#include "BasicLayers.h"
|
||||
|
||||
#define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "Gonk" , ## args)
|
||||
@ -225,6 +226,8 @@ nsWindow::DoDraw(void)
|
||||
if (listener) {
|
||||
listener->PaintWindow(gWindowToRedraw, region, 0);
|
||||
}
|
||||
} else if (mozilla::layers::LAYERS_CLIENT == lm->GetBackendType()) {
|
||||
// No need to do anything, the compositor will handle drawing
|
||||
} else if (mozilla::layers::LAYERS_BASIC == lm->GetBackendType()) {
|
||||
MOZ_ASSERT(sFramebufferOpen || sUsingOMTC);
|
||||
nsRefPtr<gfxASurface> targetSurface;
|
||||
@ -552,7 +555,12 @@ nsWindow::GetLayerManager(PLayerTransactionChild* aShadowManager,
|
||||
if (mLayerManager->GetBackendType() == LAYERS_BASIC) {
|
||||
BasicLayerManager* manager =
|
||||
static_cast<BasicLayerManager*>(mLayerManager.get());
|
||||
manager->SetDefaultTargetConfiguration(mozilla::layers::BUFFER_NONE,
|
||||
manager->SetDefaultTargetConfiguration(mozilla::layers::BUFFER_NONE,
|
||||
ScreenRotation(EffectiveScreenRotation()));
|
||||
} else if (mLayerManager->GetBackendType() == LAYERS_CLIENT) {
|
||||
ClientLayerManager* manager =
|
||||
static_cast<ClientLayerManager*>(mLayerManager.get());
|
||||
manager->SetDefaultTargetConfiguration(mozilla::layers::BUFFER_NONE,
|
||||
ScreenRotation(EffectiveScreenRotation()));
|
||||
}
|
||||
return mLayerManager;
|
||||
@ -606,7 +614,7 @@ nsWindow::GetLayerManager(PLayerTransactionChild* aShadowManager,
|
||||
NS_RUNTIMEABORT("Can't open GL context and can't fall back on /dev/graphics/fb0 ...");
|
||||
}
|
||||
|
||||
mLayerManager = new BasicShadowLayerManager(this);
|
||||
mLayerManager = new ClientLayerManager(this);
|
||||
mUseLayersAcceleration = false;
|
||||
|
||||
return mLayerManager;
|
||||
|
@ -2123,15 +2123,6 @@ nsWindow::OnExposeEvent(cairo_t *cr)
|
||||
}
|
||||
// If this widget uses OMTC...
|
||||
if (GetLayerManager()->AsShadowForwarder() && GetLayerManager()->AsShadowForwarder()->HasShadowManager()) {
|
||||
#if defined(MOZ_WIDGET_GTK2)
|
||||
nsRefPtr<gfxContext> ctx = new gfxContext(GetThebesSurface());
|
||||
#else
|
||||
nsRefPtr<gfxContext> ctx = new gfxContext(GetThebesSurface(cr));
|
||||
#endif
|
||||
nsBaseWidget::AutoLayerManagerSetup
|
||||
setupLayerManager(this, ctx, mozilla::layers::BUFFER_NONE);
|
||||
|
||||
listener->PaintWindow(this, region, 0);
|
||||
listener->DidPaintWindow();
|
||||
|
||||
g_free(rects);
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "FrameworkView.h"
|
||||
#include "nsTextStore.h"
|
||||
#include "Layers.h"
|
||||
#include "ClientLayerManager.h"
|
||||
#include "BasicLayers.h"
|
||||
#include "Windows.Graphics.Display.h"
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
@ -847,7 +848,7 @@ MetroWidget::GetLayerManager(PLayerTransactionChild* aShadowManager,
|
||||
if (!mLayerManager) {
|
||||
if (!mView) {
|
||||
NS_WARNING("Using temporary basic layer manager.");
|
||||
mLayerManager = new BasicShadowLayerManager(this);
|
||||
mLayerManager = new BasicLayerManager(this);
|
||||
mTempBasicLayerInUse = true;
|
||||
} else {
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
#include "base/basictypes.h"
|
||||
|
||||
#include "BasicLayers.h"
|
||||
#include "ClientLayerManager.h"
|
||||
#include "gfxPlatform.h"
|
||||
#if defined(MOZ_ENABLE_D3D10_LAYER)
|
||||
# include "LayerManagerD3D10.h"
|
||||
@ -322,7 +322,7 @@ PuppetWidget::GetLayerManager(PLayerTransactionChild* aShadowManager,
|
||||
}
|
||||
#endif
|
||||
if (!mLayerManager) {
|
||||
mLayerManager = new BasicShadowLayerManager(this);
|
||||
mLayerManager = new ClientLayerManager(this);
|
||||
mLayerManager->AsShadowForwarder()->SetShadowManager(aShadowManager);
|
||||
}
|
||||
}
|
||||
@ -570,6 +570,11 @@ PuppetWidget::Paint()
|
||||
|
||||
if (mozilla::layers::LAYERS_D3D10 == mLayerManager->GetBackendType()) {
|
||||
mAttachedWidgetListener->PaintWindow(this, region, 0);
|
||||
} else if (mozilla::layers::LAYERS_CLIENT == mLayerManager->GetBackendType()) {
|
||||
// Do nothing, the compositor will handle drawing
|
||||
if (mTabChild) {
|
||||
mTabChild->NotifyPainted();
|
||||
}
|
||||
} else {
|
||||
nsRefPtr<gfxContext> ctx = new gfxContext(mSurface);
|
||||
ctx->Rectangle(gfxRect(0,0,0,0));
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "nsIServiceManager.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "BasicLayers.h"
|
||||
#include "ClientLayerManager.h"
|
||||
#include "LayerManagerOGL.h"
|
||||
#include "mozilla/layers/Compositor.h"
|
||||
#include "nsIXULRuntime.h"
|
||||
@ -878,7 +879,7 @@ void nsBaseWidget::CreateCompositor(int aWidth, int aHeight)
|
||||
{
|
||||
mCompositorParent = NewCompositorParent(aWidth, aHeight);
|
||||
AsyncChannel *parentChannel = mCompositorParent->GetIPCChannel();
|
||||
LayerManager* lm = CreateBasicLayerManager();
|
||||
LayerManager* lm = new ClientLayerManager(this);
|
||||
MessageLoop *childMessageLoop = CompositorParent::CompositorLoop();
|
||||
mCompositorChild = new CompositorChild(lm);
|
||||
AsyncChannel::Side childSide = mozilla::ipc::AsyncChannel::Child;
|
||||
@ -971,7 +972,7 @@ LayerManager* nsBaseWidget::GetLayerManager(PLayerTransactionChild* aShadowManag
|
||||
|
||||
BasicLayerManager* nsBaseWidget::CreateBasicLayerManager()
|
||||
{
|
||||
return new BasicShadowLayerManager(this);
|
||||
return new BasicLayerManager(this);
|
||||
}
|
||||
|
||||
CompositorChild* nsBaseWidget::GetRemoteRenderer()
|
||||
|
Loading…
Reference in New Issue
Block a user