This commit is contained in:
Robert O'Callahan 2010-09-02 23:14:25 +12:00
Родитель df7ddc69f9
Коммит cfb7f48514
25 изменённых файлов: 162 добавлений и 521 удалений

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

@ -63,7 +63,6 @@
using namespace mozilla;
using namespace mozilla::gl;
using namespace mozilla::layers;
nsresult NS_NewCanvasRenderingContextWebGL(nsICanvasRenderingContextWebGL** aResult);
@ -509,7 +508,7 @@ WebGLContext::GetCanvasLayer(CanvasLayer *aOldLayer,
LayerManager *aManager)
{
if (!mResetLayer && aOldLayer &&
aOldLayer->HasUserData(&gWebGLLayerUserData)) {
aOldLayer->GetUserData() == &gWebGLLayerUserData) {
NS_ADDREF(aOldLayer);
if (mInvalidated) {
aOldLayer->Updated(nsIntRect(0, 0, mWidth, mHeight));
@ -523,7 +522,7 @@ WebGLContext::GetCanvasLayer(CanvasLayer *aOldLayer,
NS_WARNING("CreateCanvasLayer returned null!");
return nsnull;
}
canvasLayer->SetUserData(&gWebGLLayerUserData, nsnull);
canvasLayer->SetUserData(&gWebGLLayerUserData);
CanvasLayer::Data data;
@ -543,8 +542,7 @@ WebGLContext::GetCanvasLayer(CanvasLayer *aOldLayer,
data.mGLBufferIsPremultiplied = PR_FALSE;
canvasLayer->Initialize(data);
PRUint32 flags = gl->CreationFormat().alpha == 0 ? Layer::CONTENT_OPAQUE : 0;
canvasLayer->SetContentFlags(flags);
canvasLayer->SetIsOpaqueContent(gl->CreationFormat().alpha == 0 ? PR_TRUE : PR_FALSE);
canvasLayer->Updated(nsIntRect(0, 0, mWidth, mHeight));
mInvalidated = PR_FALSE;

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

@ -4154,7 +4154,7 @@ nsCanvasRenderingContext2D::GetCanvasLayer(CanvasLayer *aOldLayer,
return nsnull;
if (!mResetLayer && aOldLayer &&
aOldLayer->HasUserData(&g2DContextLayerUserData)) {
aOldLayer->GetUserData() == &g2DContextLayerUserData) {
NS_ADDREF(aOldLayer);
// XXX Need to just update the changed area here
aOldLayer->Updated(nsIntRect(0, 0, mWidth, mHeight));
@ -4166,7 +4166,7 @@ nsCanvasRenderingContext2D::GetCanvasLayer(CanvasLayer *aOldLayer,
NS_WARNING("CreateCanvasLayer returned null!");
return nsnull;
}
canvasLayer->SetUserData(&g2DContextLayerUserData, nsnull);
canvasLayer->SetUserData(&g2DContextLayerUserData);
CanvasLayer::Data data;
@ -4174,8 +4174,7 @@ nsCanvasRenderingContext2D::GetCanvasLayer(CanvasLayer *aOldLayer,
data.mSize = nsIntSize(mWidth, mHeight);
canvasLayer->Initialize(data);
PRUint32 flags = mOpaque ? Layer::CONTENT_OPAQUE : 0;
canvasLayer->SetContentFlags(flags);
canvasLayer->SetIsOpaqueContent(mOpaque);
canvasLayer->Updated(nsIntRect(0, 0, mWidth, mHeight));
mResetLayer = PR_FALSE;

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

@ -147,7 +147,7 @@ Layer::CanUseOpaqueSurface()
{
// If the visible content in the layer is opaque, there is no need
// for an alpha channel.
if (GetContentFlags() & CONTENT_OPAQUE)
if (IsOpaqueContent())
return PR_TRUE;
// Also, if this layer is the bottommost layer in a container which
// doesn't need an alpha channel, we can use an opaque surface for this
@ -221,24 +221,14 @@ Layer::PrintInfo(nsACString& aTo, const char* aPrefix)
if (mUseClipRect) {
AppendToString(aTo, mClipRect, " [clip=", "]");
}
if (!mTransform.IsIdentity()) {
if (!mTransform.IsIdentity())
AppendToString(aTo, mTransform, " [transform=", "]");
}
if (!mVisibleRegion.IsEmpty()) {
if (!mVisibleRegion.IsEmpty())
AppendToString(aTo, mVisibleRegion, " [visible=", "]");
}
if (1.0 != mOpacity) {
if (1.0 != mOpacity)
aTo.AppendPrintf(" [opacity=%g]", mOpacity);
}
if (GetContentFlags() & CONTENT_OPAQUE) {
if (IsOpaqueContent())
aTo += " [opaqueContent]";
}
if (GetContentFlags() & CONTENT_NO_TEXT) {
aTo += " [noText]";
}
if (GetContentFlags() & CONTENT_NO_TEXT_OVER_TRANSPARENT) {
aTo += " [noTextOverTransparent]";
}
return aTo;
}

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

@ -83,14 +83,6 @@ class SpecificLayerAttributes;
virtual const char* Name() const { return n; } \
virtual LayerType GetType() const { return e; }
/**
* Base class for userdata objects attached to layers and layer managers.
*/
class THEBES_API LayerUserData {
public:
virtual ~LayerUserData() {}
};
/*
* Motivation: For truly smooth animation and video playback, we need to
* be able to compose frames and render them on a dedicated thread (i.e.
@ -117,52 +109,6 @@ public:
* BasicLayerManager for such an implementation.
*/
/**
* Helper class to manage user data for layers and LayerManagers.
*/
class THEBES_API LayerUserDataSet {
public:
LayerUserDataSet() : mKey(nsnull) {}
void Set(void* aKey, LayerUserData* aValue)
{
NS_ASSERTION(!mKey || mKey == aKey,
"Multiple LayerUserData objects not supported");
mKey = aKey;
mValue = aValue;
}
/**
* This can be used anytime. Ownership passes to the caller!
*/
LayerUserData* Remove(void* aKey)
{
if (mKey == aKey) {
mKey = nsnull;
LayerUserData* d = mValue.forget();
return d;
}
return nsnull;
}
/**
* This getter can be used anytime.
*/
PRBool Has(void* aKey)
{
return mKey == aKey;
}
/**
* This getter can be used anytime. Ownership is retained by this object.
*/
LayerUserData* Get(void* aKey)
{
return mKey == aKey ? mValue.get() : nsnull;
}
private:
void* mKey;
nsAutoPtr<LayerUserData> mValue;
};
/**
* A LayerManager controls a tree of layers. All layers in the tree
* must use the same LayerManager.
@ -196,7 +142,7 @@ public:
LAYERS_D3D9
};
LayerManager() : mDestroyed(PR_FALSE)
LayerManager() : mUserData(nsnull), mDestroyed(PR_FALSE)
{
InitLog();
}
@ -321,28 +267,10 @@ public:
*/
virtual LayersBackend GetBackendType() = 0;
/**
* This setter can be used anytime. The user data for all keys is
* initially null. Ownership pases to the layer manager.
*/
void SetUserData(void* aKey, LayerUserData* aData)
{ mUserData.Set(aKey, aData); }
/**
* This can be used anytime. Ownership passes to the caller!
*/
nsAutoPtr<LayerUserData> RemoveUserData(void* aKey)
{ nsAutoPtr<LayerUserData> d(mUserData.Remove(aKey)); return d; }
/**
* This getter can be used anytime.
*/
PRBool HasUserData(void* aKey)
{ return mUserData.Has(aKey); }
/**
* This getter can be used anytime. Ownership is retained by the layer
* manager.
*/
LayerUserData* GetUserData(void* aKey)
{ return mUserData.Get(aKey); }
// This setter and getter can be used anytime. The user data is initially
// null.
void SetUserData(void* aData) { mUserData = aData; }
void* GetUserData() { return mUserData; }
// We always declare the following logging symbols, because it's
// extremely tricky to conditionally declare them. However, for
@ -377,7 +305,7 @@ public:
protected:
nsRefPtr<Layer> mRoot;
LayerUserDataSet mUserData;
void* mUserData;
PRPackedBool mDestroyed;
// Print interesting information about this into aTo. Internally
@ -416,37 +344,17 @@ public:
*/
LayerManager* Manager() { return mManager; }
enum {
/**
* If this is set, the caller is promising that by the end of this
* transaction the entire visible region (as specified by
* SetVisibleRegion) will be filled with opaque content.
*/
CONTENT_OPAQUE = 0x01,
/**
* ThebesLayers only!
* If this is set, the caller is promising that the visible region
* contains no text at all. If this is set,
* CONTENT_NO_TEXT_OVER_TRANSPARENT will also be set.
*/
CONTENT_NO_TEXT = 0x02,
/**
* ThebesLayers only!
* If this is set, the caller is promising that the visible region
* contains no text over transparent pixels (any text, if present,
* is over fully opaque pixels).
*/
CONTENT_NO_TEXT_OVER_TRANSPARENT = 0x04
};
/**
* CONSTRUCTION PHASE ONLY
* This lets layout make some promises about what will be drawn into the
* visible region of the ThebesLayer. This enables internal quality
* and performance optimizations.
* If this is called with aOpaque set to true, the caller is promising
* that by the end of this transaction the entire visible region
* (as specified by SetVisibleRegion) will be filled with opaque
* content. This enables some internal quality and performance
* optimizations.
*/
void SetContentFlags(PRUint32 aFlags)
void SetIsOpaqueContent(PRBool aOpaque)
{
mContentFlags = aFlags;
mIsOpaqueContent = aOpaque;
Mutated();
}
/**
@ -529,7 +437,7 @@ public:
// These getters can be used anytime.
float GetOpacity() { return mOpacity; }
const nsIntRect* GetClipRect() { return mUseClipRect ? &mClipRect : nsnull; }
PRUint32 GetContentFlags() { return mContentFlags; }
PRBool IsOpaqueContent() { return mIsOpaqueContent; }
const nsIntRegion& GetVisibleRegion() { return mVisibleRegion; }
ContainerLayer* GetParent() { return mParent; }
Layer* GetNextSibling() { return mNextSibling; }
@ -552,28 +460,10 @@ public:
// quality.
PRBool CanUseOpaqueSurface();
/**
* This setter can be used anytime. The user data for all keys is
* initially null. Ownership pases to the layer manager.
*/
void SetUserData(void* aKey, LayerUserData* aData)
{ mUserData.Set(aKey, aData); }
/**
* This can be used anytime. Ownership passes to the caller!
*/
nsAutoPtr<LayerUserData> RemoveUserData(void* aKey)
{ nsAutoPtr<LayerUserData> d(mUserData.Remove(aKey)); return d; }
/**
* This getter can be used anytime.
*/
PRBool HasUserData(void* aKey)
{ return mUserData.Has(aKey); }
/**
* This getter can be used anytime. Ownership is retained by the layer
* manager.
*/
LayerUserData* GetUserData(void* aKey)
{ return mUserData.Get(aKey); }
// This setter and getter can be used anytime. The user data is initially
// null.
void SetUserData(void* aData) { mUserData = aData; }
void* GetUserData() { return mUserData; }
/**
* Dynamic downcast to a Thebes layer. Returns null if this is not
@ -629,9 +519,10 @@ protected:
mNextSibling(nsnull),
mPrevSibling(nsnull),
mImplData(aImplData),
mUserData(nsnull),
mOpacity(1.0),
mContentFlags(0),
mUseClipRect(PR_FALSE)
mUseClipRect(PR_FALSE),
mIsOpaqueContent(PR_FALSE)
{}
void Mutated() { mManager->Mutated(this); }
@ -648,13 +539,13 @@ protected:
Layer* mNextSibling;
Layer* mPrevSibling;
void* mImplData;
LayerUserDataSet mUserData;
void* mUserData;
nsIntRegion mVisibleRegion;
gfx3DMatrix mTransform;
float mOpacity;
nsIntRect mClipRect;
PRUint32 mContentFlags;
PRPackedBool mUseClipRect;
PRPackedBool mIsOpaqueContent;
};
/**

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

@ -367,23 +367,6 @@ InheritContextFlags(gfxContext* aSource, gfxContext* aDest)
}
}
static PRBool
ShouldRetainTransparentSurface(PRUint32 aContentFlags,
gfxASurface* aTargetSurface)
{
if (aContentFlags & Layer::CONTENT_NO_TEXT)
return PR_TRUE;
switch (aTargetSurface->GetTextQualityInTransparentSurfaces()) {
case gfxASurface::TEXT_QUALITY_OK:
return PR_TRUE;
case gfxASurface::TEXT_QUALITY_OK_OVER_OPAQUE_PIXELS:
return (aContentFlags & Layer::CONTENT_NO_TEXT_OVER_TRANSPARENT) != 0;
default:
return PR_FALSE;
}
}
void
BasicThebesLayer::Paint(gfxContext* aContext,
LayerManager::DrawThebesLayerCallback aCallback,
@ -394,20 +377,15 @@ BasicThebesLayer::Paint(gfxContext* aContext,
"Can only draw in drawing phase");
gfxContext* target = BasicManager()->GetTarget();
NS_ASSERTION(target, "We shouldn't be called if there's no target");
nsRefPtr<gfxASurface> targetSurface = aContext->CurrentSurface();
PRBool canUseOpaqueSurface = CanUseOpaqueSurface();
if (!BasicManager()->IsRetained() ||
(aOpacity == 1.0 && !canUseOpaqueSurface &&
!ShouldRetainTransparentSurface(mContentFlags, targetSurface))) {
mValidRegion.SetEmpty();
mBuffer.Clear();
if (!BasicManager()->IsRetained()) {
if (aOpacity != 1.0) {
target->Save();
ClipToContain(target, mVisibleRegion.GetBounds());
target->PushGroup(gfxASurface::CONTENT_COLOR_ALPHA);
}
mValidRegion.SetEmpty();
mBuffer.Clear();
aCallback(this, target, mVisibleRegion, nsIntRegion(), aCallbackData);
if (aOpacity != 1.0) {
target->PopGroupToSource();
@ -417,12 +395,15 @@ BasicThebesLayer::Paint(gfxContext* aContext,
return;
}
nsRefPtr<gfxASurface> targetSurface = aContext->CurrentSurface();
PRBool isOpaqueContent =
(targetSurface->AreSimilarSurfacesSensitiveToContentType() &&
aOpacity == 1.0 &&
CanUseOpaqueSurface());
{
PRBool opaqueBuffer = canUseOpaqueSurface &&
targetSurface->AreSimilarSurfacesSensitiveToContentType();
Buffer::ContentType contentType =
opaqueBuffer ? gfxASurface::CONTENT_COLOR :
gfxASurface::CONTENT_COLOR_ALPHA;
isOpaqueContent ? gfxASurface::CONTENT_COLOR :
gfxASurface::CONTENT_COLOR_ALPHA;
Buffer::PaintState state = mBuffer.BeginPaint(this, contentType);
mValidRegion.Sub(mValidRegion, state.mRegionToInvalidate);
@ -444,7 +425,7 @@ BasicThebesLayer::Paint(gfxContext* aContext,
}
}
mBuffer.DrawTo(this, canUseOpaqueSurface, target, aOpacity);
mBuffer.DrawTo(this, isOpaqueContent, target, aOpacity);
}
void
@ -701,7 +682,7 @@ BasicCanvasLayer::Updated(const nsIntRect& aRect)
if (mGLContext) {
nsRefPtr<gfxImageSurface> isurf =
new gfxImageSurface(gfxIntSize(mBounds.width, mBounds.height),
(GetContentFlags() & CONTENT_OPAQUE)
IsOpaqueContent()
? gfxASurface::ImageFormatRGB24
: gfxASurface::ImageFormatARGB32);
if (!isurf || isurf->CairoStatus() != 0) {
@ -812,7 +793,7 @@ MayHaveOverlappingOrTransparentLayers(Layer* aLayer,
const nsIntRect& aBounds,
nsIntRegion* aDirtyVisibleRegionInContainer)
{
if (!(aLayer->GetContentFlags() & Layer::CONTENT_OPAQUE)) {
if (!aLayer->IsOpaqueContent()) {
return PR_TRUE;
}

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

@ -46,6 +46,27 @@
namespace mozilla {
namespace layers {
// Returns true if it's OK to save the contents of aLayer in an
// opaque surface (a surface without an alpha channel).
// If we can use a surface without an alpha channel, we should, because
// it will often make painting of antialiased text faster and higher
// quality.
static PRBool
UseOpaqueSurface(Layer* aLayer)
{
// If the visible content in the layer is opaque, there is no need
// for an alpha channel.
if (aLayer->IsOpaqueContent())
return PR_TRUE;
// Also, if this layer is the bottommost layer in a container which
// doesn't need an alpha channel, we can use an opaque surface for this
// layer too. Any transparent areas must be covered by something else
// in the container.
ContainerLayer* parent = aLayer->GetParent();
return parent && parent->GetFirstChild() == aLayer &&
UseOpaqueSurface(parent);
}
ThebesLayerD3D9::ThebesLayerD3D9(LayerManagerD3D9 *aManager)
: ThebesLayer(aManager, NULL)
, LayerD3D9(aManager)
@ -83,7 +104,7 @@ ThebesLayerD3D9::SetVisibleRegion(const nsIntRegion &aRegion)
return;
}
D3DFORMAT fmt = (CanUseOpaqueSurface() && !mD2DSurface) ?
D3DFORMAT fmt = (UseOpaqueSurface(this) && !mD2DSurface) ?
D3DFMT_X8R8G8B8 : D3DFMT_A8R8G8B8;
D3DSURFACE_DESC desc;
@ -177,7 +198,7 @@ ThebesLayerD3D9::RenderLayer()
// We differentiate between these formats since D3D9 will only allow us to
// call GetDC on an opaque surface.
D3DFORMAT fmt = (CanUseOpaqueSurface() && !mD2DSurface) ?
D3DFORMAT fmt = (UseOpaqueSurface(this) && !mD2DSurface) ?
D3DFMT_X8R8G8B8 : D3DFMT_A8R8G8B8;
if (mTexture) {
@ -293,7 +314,7 @@ ThebesLayerD3D9::DrawRegion(const nsIntRegion &aRegion)
}
#endif
D3DFORMAT fmt = CanUseOpaqueSurface() ? D3DFMT_X8R8G8B8 : D3DFMT_A8R8G8B8;
D3DFORMAT fmt = UseOpaqueSurface(this) ? D3DFMT_X8R8G8B8 : D3DFMT_A8R8G8B8;
nsIntRect bounds = aRegion.GetBounds();
gfxASurface::gfxImageFormat imageFormat = gfxASurface::ImageFormatARGB32;
@ -306,7 +327,7 @@ ThebesLayerD3D9::DrawRegion(const nsIntRegion &aRegion)
nsRefPtr<IDirect3DSurface9> surf;
HDC dc;
if (CanUseOpaqueSurface()) {
if (UseOpaqueSurface(this)) {
hr = tmpTexture->GetSurfaceLevel(0, getter_AddRefs(surf));
if (FAILED(hr)) {
@ -339,7 +360,7 @@ ThebesLayerD3D9::DrawRegion(const nsIntRegion &aRegion)
LayerManagerD3D9::CallbackInfo cbInfo = mD3DManager->GetCallbackInfo();
cbInfo.Callback(this, context, aRegion, nsIntRegion(), cbInfo.CallbackData);
if (CanUseOpaqueSurface()) {
if (UseOpaqueSurface(this)) {
surf->ReleaseDC(dc);
} else {
D3DLOCKED_RECT r;
@ -402,7 +423,7 @@ ThebesLayerD3D9::CreateNewTexture(const gfxIntSize &aSize)
D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8,
D3DPOOL_DEFAULT, getter_AddRefs(mTexture), &sharedHandle);
mD2DSurface = new gfxD2DSurface(sharedHandle, CanUseOpaqueSurface() ?
mD2DSurface = new gfxD2DSurface(sharedHandle, UseOpaqueSurface(this) ?
gfxASurface::CONTENT_COLOR : gfxASurface::CONTENT_COLOR_ALPHA);
// If there's an error, go on and do what we always do.
@ -415,7 +436,7 @@ ThebesLayerD3D9::CreateNewTexture(const gfxIntSize &aSize)
#endif
if (!mTexture) {
device()->CreateTexture(aSize.width, aSize.height, 1,
D3DUSAGE_RENDERTARGET, CanUseOpaqueSurface() ? D3DFMT_X8R8G8B8 : D3DFMT_A8R8G8B8,
D3DUSAGE_RENDERTARGET, UseOpaqueSurface(this) ? D3DFMT_X8R8G8B8 : D3DFMT_A8R8G8B8,
D3DPOOL_DEFAULT, getter_AddRefs(mTexture), NULL);
}
}

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

@ -93,7 +93,7 @@ struct OpCreateImageBuffer {
struct CommonLayerAttributes {
nsIntRegion visibleRegion;
gfx3DMatrix transform;
PRUint32 contentFlags;
bool isOpaqueContent;
float opacity;
bool useClipRect;
nsIntRect clipRect;

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

@ -271,7 +271,7 @@ ShadowLayerForwarder::EndTransaction(nsTArray<EditReply>* aReplies)
CommonLayerAttributes& common = attrs.common();
common.visibleRegion() = mutant->GetVisibleRegion();
common.transform() = mutant->GetTransform();
common.contentFlags() = mutant->GetContentFlags();
common.isOpaqueContent() = mutant->IsOpaqueContent();
common.opacity() = mutant->GetOpacity();
common.useClipRect() = !!mutant->GetClipRect();
common.clipRect() = (common.useClipRect() ?

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

@ -229,7 +229,7 @@ ShadowLayersParent::RecvUpdate(const nsTArray<Edit>& cset,
const CommonLayerAttributes& common = attrs.common();
layer->SetVisibleRegion(common.visibleRegion());
layer->SetContentFlags(common.contentFlags());
layer->SetIsOpaqueContent(common.isOpaqueContent());
layer->SetOpacity(common.opacity());
layer->SetClipRect(common.useClipRect() ? &common.clipRect() : NULL);
layer->SetTransform(common.transform());

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

@ -153,40 +153,7 @@ public:
*/
virtual PRBool AreSimilarSurfacesSensitiveToContentType()
{
return PR_TRUE;
}
enum TextQuality {
/**
* TEXT_QUALITY_OK means that text is always rendered to a
* transparent surface just as well as it would be rendered to an
* opaque surface. This would normally only be true if
* subpixel antialiasing is disabled or if the platform's
* transparent surfaces support component alpha.
*/
TEXT_QUALITY_OK,
/**
* TEXT_QUALITY_OK_OVER_OPAQUE_PIXELS means that text is rendered
* to a transparent surface just as well as it would be rendered to an
* opaque surface, but only if all the pixels the text is drawn
* over already have opaque alpha values.
*/
TEXT_QUALITY_OK_OVER_OPAQUE_PIXELS,
/**
* TEXT_QUALITY_BAD means that text is rendered
* to a transparent surface worse than it would be rendered to an
* opaque surface, even if all the pixels the text is drawn
* over already have opaque alpha values.
*/
TEXT_QUALITY_BAD
};
/**
* Determine how well text would be rendered in transparent surfaces that
* are similar to this surface.
*/
virtual TextQuality GetTextQualityInTransparentSurfaces()
{
return TEXT_QUALITY_BAD;
return PR_TRUE;
}
int CairoStatus();

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

@ -57,12 +57,6 @@ public:
virtual ~gfxD2DSurface();
virtual TextQuality GetTextQualityInTransparentSurfaces()
{
// D2D always draws text in transparent surfaces with grayscale-AA,
// even if the text is over opaque pixels.
return TEXT_QUALITY_BAD;
}
void Present();
void Scroll(const nsIntPoint &aDelta, const nsIntRect &aClip);

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

@ -60,10 +60,6 @@ public:
{
return PR_FALSE;
}
virtual TextQuality GetTextQualityInTransparentSurfaces()
{
return TEXT_QUALITY_OK_OVER_OPAQUE_PIXELS;
}
const gfxSize& GetSize() const { return mSize; }

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

@ -81,11 +81,6 @@ public:
const gfxIntSize& size,
gfxImageFormat format);
virtual TextQuality GetTextQualityInTransparentSurfaces()
{
return TEXT_QUALITY_OK_OVER_OPAQUE_PIXELS;
}
nsresult BeginPrinting(const nsAString& aTitle, const nsAString& aPrintToFileName);
nsresult EndPrinting();
nsresult AbortPrinting();

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

@ -77,11 +77,6 @@ public:
virtual already_AddRefed<gfxASurface>
CreateSimilarSurface(gfxContentType aType, const gfxIntSize& aSize);
virtual TextQuality GetTextQualityInTransparentSurfaces()
{
return TEXT_QUALITY_OK_OVER_OPAQUE_PIXELS;
}
const gfxIntSize& GetSize() { return mSize; }
Display* XDisplay() { return mDisplay; }

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

@ -57,22 +57,14 @@ namespace {
/**
* This is the userdata we associate with a layer manager.
*/
class LayerManagerData : public LayerUserData {
class LayerManagerData {
public:
LayerManagerData() :
mInvalidateAllThebesContent(PR_FALSE),
mInvalidateAllLayers(PR_FALSE)
{
MOZ_COUNT_CTOR(LayerManagerData);
mFramesWithLayers.Init();
}
~LayerManagerData() {
// Remove display item data properties now, since we won't be able
// to find these frames again without mFramesWithLayers.
mFramesWithLayers.EnumerateEntries(
FrameLayerBuilder::RemoveDisplayItemDataForFrame, nsnull);
MOZ_COUNT_DTOR(LayerManagerData);
}
/**
* Tracks which frames have layers associated with them.
@ -159,8 +151,7 @@ protected:
public:
ThebesLayerData() :
mActiveScrolledRoot(nsnull), mLayer(nsnull),
mIsSolidColorInVisibleRegion(PR_FALSE),
mHasText(PR_FALSE), mHasTextOverTransparent(PR_FALSE) {}
mIsSolidColorInVisibleRegion(PR_FALSE) {}
/**
* Record that an item has been added to the ThebesLayer, so we
* need to update our regions.
@ -174,10 +165,10 @@ protected:
* @param aSolidColor if non-null, the visible area of the item is
* a constant color given by *aSolidColor
*/
void Accumulate(nsDisplayListBuilder* aBuilder,
nsDisplayItem* aItem,
const nsIntRect& aVisibleRect,
const nsIntRect& aDrawRect);
void Accumulate(const nsIntRect& aVisibleRect,
const nsIntRect& aDrawRect,
const nsIntRect* aOpaqueRect,
nscolor* aSolidColor);
nsIFrame* GetActiveScrolledRoot() { return mActiveScrolledRoot; }
/**
@ -229,15 +220,6 @@ protected:
* True if every pixel in mVisibleRegion will have color mSolidColor.
*/
PRPackedBool mIsSolidColorInVisibleRegion;
/**
* True if there is any text visible in the layer.
*/
PRPackedBool mHasText;
/**
* True if there is any text visible in the layer that's over
* transparent pixels in the layer.
*/
PRPackedBool mHasTextOverTransparent;
};
/**
@ -263,12 +245,6 @@ protected:
* aItem in that layer.
*/
void InvalidateForLayerChange(nsDisplayItem* aItem, Layer* aNewLayer);
/**
* Try to determine whether the ThebesLayer at aThebesLayerIndex
* has an opaque single color covering the visible area behind it.
* If successful, return that color, otherwise return NS_RGBA(0,0,0,0).
*/
nscolor FindOpaqueBackgroundColorFor(PRInt32 aThebesLayerIndex);
/**
* Indicate that we are done adding items to the ThebesLayer at the top of
* mThebesLayerDataStack. Set the final visible region and opaque-content
@ -292,10 +268,11 @@ protected:
* @param aSolidColor if non-null, indicates that every pixel in aVisibleRect
* will be painted with aSolidColor by the item
*/
already_AddRefed<ThebesLayer> FindThebesLayerFor(nsDisplayItem* aItem,
const nsIntRect& aVisibleRect,
already_AddRefed<ThebesLayer> FindThebesLayerFor(const nsIntRect& aVisibleRect,
const nsIntRect& aDrawRect,
nsIFrame* aActiveScrolledRoot);
nsIFrame* aActiveScrolledRoot,
const nsIntRect* aOpaqueRect,
nscolor* aSolidColor);
ThebesLayerData* GetTopThebesLayerData()
{
return mThebesLayerDataStack.IsEmpty() ? nsnull
@ -325,37 +302,20 @@ protected:
PRPackedBool mInvalidateAllThebesContent;
};
class ThebesDisplayItemLayerUserData : public LayerUserData
{
public:
ThebesDisplayItemLayerUserData() :
mForcedBackgroundColor(NS_RGBA(0,0,0,0)) {}
nscolor mForcedBackgroundColor;
};
/**
* The address of gThebesDisplayItemLayerUserData is used as the user
* data key for ThebesLayers created by FrameLayerBuilder.
* data pointer for ThebesLayers created by FrameLayerBuilder.
* It identifies ThebesLayers used to draw non-layer content, which are
* therefore eligible for recycling. We want display items to be able to
* create their own dedicated ThebesLayers in BuildLayer, if necessary,
* and we wouldn't want to accidentally recycle those.
* The user data is a ThebesDisplayItemLayerUserData.
*/
PRUint8 gThebesDisplayItemLayerUserData;
static PRUint8 gThebesDisplayItemLayerUserData;
/**
* The address of gColorLayerUserData is used as the user
* data key for ColorLayers created by FrameLayerBuilder.
* The user data is null.
* data pointer for ColorLayers
*/
PRUint8 gColorLayerUserData;
/**
* The address of gLayerManagerUserData is used as the user
* data key for retained LayerManagers managed by FrameLayerBuilder.
* The user data is a LayerManagerData.
*/
PRUint8 gLayerManagerUserData;
static PRUint8 gColorLayerUserData;
} // anonymous namespace
@ -382,11 +342,12 @@ FrameLayerBuilder::InternalDestroyDisplayItemData(nsIFrame* aFrame,
if (aRemoveFromFramesWithLayers) {
LayerManager* manager = array->ElementAt(0).mLayer->Manager();
LayerManagerData* data = static_cast<LayerManagerData*>
(manager->GetUserData(&gLayerManagerUserData));
(manager->GetUserData());
NS_ASSERTION(data, "Frame with layer should have been recorded");
data->mFramesWithLayers.RemoveEntry(aFrame);
if (data->mFramesWithLayers.Count() == 0) {
manager->RemoveUserData(&gLayerManagerUserData);
delete data;
manager->SetUserData(nsnull);
// Consume the reference we added when we set the user data
// in DidEndTransaction. But don't actually release until we've
// released all the layers in the DisplayItemData array below!
@ -410,7 +371,7 @@ FrameLayerBuilder::WillBeginRetainedLayerTransaction(LayerManager* aManager)
{
mRetainingManager = aManager;
LayerManagerData* data = static_cast<LayerManagerData*>
(aManager->GetUserData(&gLayerManagerUserData));
(aManager->GetUserData());
if (data) {
mInvalidateAllThebesContent = data->mInvalidateAllThebesContent;
mInvalidateAllLayers = data->mInvalidateAllLayers;
@ -459,13 +420,13 @@ FrameLayerBuilder::WillEndTransaction(LayerManager* aManager)
// correctly and the NS_FRAME_HAS_CONTAINER_LAYER bits will be set
// correctly.
LayerManagerData* data = static_cast<LayerManagerData*>
(mRetainingManager->GetUserData(&gLayerManagerUserData));
(mRetainingManager->GetUserData());
if (data) {
// Update all the frames that used to have layers.
data->mFramesWithLayers.EnumerateEntries(UpdateDisplayItemDataForFrame, this);
} else {
data = new LayerManagerData();
mRetainingManager->SetUserData(&gLayerManagerUserData, data);
mRetainingManager->SetUserData(data);
// Addref mRetainingManager. We'll release it when 'data' is
// removed.
NS_ADDREF(mRetainingManager);
@ -489,7 +450,7 @@ FrameLayerBuilder::UpdateDisplayItemDataForFrame(nsPtrHashKey<nsIFrame>* aEntry,
nsIFrame* f = aEntry->GetKey();
FrameProperties props = f->Properties();
DisplayItemDataEntry* newDisplayItems =
builder ? builder->mNewDisplayItemData.GetEntry(f) : nsnull;
builder->mNewDisplayItemData.GetEntry(f);
if (!newDisplayItems) {
// This frame was visible, but isn't anymore.
PRBool found;
@ -634,7 +595,7 @@ ContainerState::CreateOrRecycleColorLayer()
if (!layer)
return nsnull;
// Mark this layer as being used for Thebes-painting display items
layer->SetUserData(&gColorLayerUserData, nsnull);
layer->SetUserData(&gColorLayerUserData);
}
return layer.forget();
}
@ -676,8 +637,7 @@ ContainerState::CreateOrRecycleThebesLayer(nsIFrame* aActiveScrolledRoot)
if (!layer)
return nsnull;
// Mark this layer as being used for Thebes-painting display items
layer->SetUserData(&gThebesDisplayItemLayerUserData,
new ThebesDisplayItemLayerUserData());
layer->SetUserData(&gThebesDisplayItemLayerUserData);
}
// Set up transform so that 0,0 in the Thebes layer corresponds to the
@ -737,39 +697,6 @@ SetVisibleRectForLayer(Layer* aLayer, const nsIntRect& aRect)
}
}
nscolor
ContainerState::FindOpaqueBackgroundColorFor(PRInt32 aThebesLayerIndex)
{
ThebesLayerData* target = mThebesLayerDataStack[aThebesLayerIndex];
for (PRInt32 i = aThebesLayerIndex - 1; i >= 0; --i) {
ThebesLayerData* candidate = mThebesLayerDataStack[i];
nsIntRegion visibleAboveIntersection;
visibleAboveIntersection.And(candidate->mVisibleAboveRegion, target->mVisibleRegion);
if (!visibleAboveIntersection.IsEmpty()) {
// Some non-Thebes content between target and candidate; this is
// hopeless
break;
}
nsIntRegion intersection;
intersection.And(candidate->mVisibleRegion, target->mVisibleRegion);
if (intersection.IsEmpty()) {
// The layer doesn't intersect our target, ignore it and move on
continue;
}
// The candidate intersects our target. If any layer has a solid-color
// area behind our target, this must be it. Scan its display items.
nsPresContext* presContext = mContainerFrame->PresContext();
nscoord appUnitsPerDevPixel = presContext->AppUnitsPerDevPixel();
nsRect rect =
target->mVisibleRegion.GetBounds().ToAppUnits(appUnitsPerDevPixel);
return mBuilder->LayerBuilder()->
FindOpaqueColorCovering(mBuilder, candidate->mLayer, rect);
}
return NS_RGBA(0,0,0,0);
}
void
ContainerState::PopThebesLayerData()
{
@ -778,6 +705,21 @@ ContainerState::PopThebesLayerData()
PRInt32 lastIndex = mThebesLayerDataStack.Length() - 1;
ThebesLayerData* data = mThebesLayerDataStack[lastIndex];
if (lastIndex > 0) {
// Since we're going to pop off the last ThebesLayerData, the
// mVisibleAboveRegion of the second-to-last item will need to include
// the regions of the last item.
ThebesLayerData* nextData = mThebesLayerDataStack[lastIndex - 1];
nextData->mVisibleAboveRegion.Or(nextData->mVisibleAboveRegion,
data->mVisibleAboveRegion);
nextData->mVisibleAboveRegion.Or(nextData->mVisibleAboveRegion,
data->mVisibleRegion);
nextData->mDrawAboveRegion.Or(nextData->mDrawAboveRegion,
data->mDrawAboveRegion);
nextData->mDrawAboveRegion.Or(nextData->mDrawAboveRegion,
data->mDrawRegion);
}
Layer* layer;
if (data->mIsSolidColorInVisibleRegion) {
nsRefPtr<ColorLayer> colorLayer = CreateOrRecycleColorLayer();
@ -824,87 +766,26 @@ ContainerState::PopThebesLayerData()
nsIntRegion transparentRegion;
transparentRegion.Sub(data->mVisibleRegion, data->mOpaqueRegion);
PRBool isOpaque = transparentRegion.IsEmpty();
// For translucent ThebesLayers, try to find an opaque background
// color that covers the entire area beneath it so we can pull that
// color into this layer to make it opaque.
if (layer == data->mLayer) {
nscolor backgroundColor = NS_RGBA(0,0,0,0);
if (!isOpaque) {
backgroundColor = FindOpaqueBackgroundColorFor(lastIndex);
if (NS_GET_A(backgroundColor) == 255) {
isOpaque = PR_TRUE;
}
}
// Store the background color
ThebesDisplayItemLayerUserData* userData =
static_cast<ThebesDisplayItemLayerUserData*>
(data->mLayer->GetUserData(&gThebesDisplayItemLayerUserData));
NS_ASSERTION(userData, "where did our user data go?");
if (userData->mForcedBackgroundColor != backgroundColor) {
// Invalidate the entire target ThebesLayer since we're changing
// the background color
data->mLayer->InvalidateRegion(data->mLayer->GetValidRegion());
}
userData->mForcedBackgroundColor = backgroundColor;
}
PRUint32 flags =
(isOpaque ? Layer::CONTENT_OPAQUE : 0) |
(data->mHasText ? 0 : Layer::CONTENT_NO_TEXT) |
(data->mHasTextOverTransparent ? 0 : Layer::CONTENT_NO_TEXT_OVER_TRANSPARENT);
layer->SetContentFlags(flags);
if (lastIndex > 0) {
// Since we're going to pop off the last ThebesLayerData, the
// mVisibleAboveRegion of the second-to-last item will need to include
// the regions of the last item.
ThebesLayerData* nextData = mThebesLayerDataStack[lastIndex - 1];
nextData->mVisibleAboveRegion.Or(nextData->mVisibleAboveRegion,
data->mVisibleAboveRegion);
nextData->mVisibleAboveRegion.Or(nextData->mVisibleAboveRegion,
data->mVisibleRegion);
nextData->mDrawAboveRegion.Or(nextData->mDrawAboveRegion,
data->mDrawAboveRegion);
nextData->mDrawAboveRegion.Or(nextData->mDrawAboveRegion,
data->mDrawRegion);
}
layer->SetIsOpaqueContent(transparentRegion.IsEmpty());
mThebesLayerDataStack.RemoveElementAt(lastIndex);
}
static PRBool
IsText(nsDisplayItem* aItem) {
switch (aItem->GetType()) {
case nsDisplayItem::TYPE_TEXT:
case nsDisplayItem::TYPE_BULLET:
case nsDisplayItem::TYPE_HEADER_FOOTER:
case nsDisplayItem::TYPE_MATHML_CHAR_FOREGROUND:
#ifdef MOZ_XUL
case nsDisplayItem::TYPE_XUL_TEXT_BOX:
#endif
return PR_TRUE;
default:
return PR_FALSE;
}
}
void
ContainerState::ThebesLayerData::Accumulate(nsDisplayListBuilder* aBuilder,
nsDisplayItem* aItem,
const nsIntRect& aVisibleRect,
const nsIntRect& aDrawRect)
ContainerState::ThebesLayerData::Accumulate(const nsIntRect& aVisibleRect,
const nsIntRect& aDrawRect,
const nsIntRect* aOpaqueRect,
nscolor* aSolidColor)
{
nscolor uniformColor;
if (aItem->IsUniform(aBuilder, &uniformColor)) {
if (aSolidColor) {
if (mVisibleRegion.IsEmpty()) {
// This color is all we have
mSolidColor = uniformColor;
mSolidColor = *aSolidColor;
mIsSolidColorInVisibleRegion = PR_TRUE;
} else if (mIsSolidColorInVisibleRegion &&
mVisibleRegion.IsEqual(nsIntRegion(aVisibleRect))) {
// we can just blend the colors together
mSolidColor = NS_ComposeColors(mSolidColor, uniformColor);
mSolidColor = NS_ComposeColors(mSolidColor, *aSolidColor);
} else {
mIsSolidColorInVisibleRegion = PR_FALSE;
}
@ -916,31 +797,26 @@ ContainerState::ThebesLayerData::Accumulate(nsDisplayListBuilder* aBuilder,
mVisibleRegion.SimplifyOutward(4);
mDrawRegion.Or(mDrawRegion, aDrawRect);
mDrawRegion.SimplifyOutward(4);
if (aItem->IsOpaque(aBuilder)) {
if (aOpaqueRect) {
// We don't use SimplifyInward here since it's not defined exactly
// what it will discard. For our purposes the most important case
// is a large opaque background at the bottom of z-order (e.g.,
// a canvas background), so we need to make sure that the first rect
// we see doesn't get discarded.
nsIntRegion tmp;
tmp.Or(mOpaqueRegion, aDrawRect);
tmp.Or(mOpaqueRegion, *aOpaqueRect);
if (tmp.GetNumRects() <= 4) {
mOpaqueRegion = tmp;
}
} else if (IsText(aItem)) {
mHasText = PR_TRUE;
if (!mOpaqueRegion.Contains(aVisibleRect)) {
mHasTextOverTransparent = PR_TRUE;
}
}
}
already_AddRefed<ThebesLayer>
ContainerState::FindThebesLayerFor(nsDisplayItem* aItem,
const nsIntRect& aVisibleRect,
ContainerState::FindThebesLayerFor(const nsIntRect& aVisibleRect,
const nsIntRect& aDrawRect,
nsIFrame* aActiveScrolledRoot)
nsIFrame* aActiveScrolledRoot,
const nsIntRect* aOpaqueRect,
nscolor* aSolidColor)
{
PRInt32 i;
PRInt32 lowestUsableLayerWithScrolledRoot = -1;
@ -994,7 +870,7 @@ ContainerState::FindThebesLayerFor(nsDisplayItem* aItem,
layer = thebesLayerData->mLayer;
}
thebesLayerData->Accumulate(mBuilder, aItem, aVisibleRect, aDrawRect);
thebesLayerData->Accumulate(aVisibleRect, aDrawRect, aOpaqueRect, aSolidColor);
return layer.forget();
}
@ -1089,7 +965,7 @@ ContainerState::ProcessDisplayItems(const nsDisplayList& aList,
// Update that layer's clip and visible rects.
NS_ASSERTION(ownLayer->Manager() == mManager, "Wrong manager");
NS_ASSERTION(!ownLayer->HasUserData(&gLayerManagerUserData),
NS_ASSERTION(ownLayer->GetUserData() != &gThebesDisplayItemLayerUserData,
"We shouldn't have a FrameLayerBuilder-managed layer here!");
// It has its own layer. Update that layer's clip and visible rects.
if (aClipRect) {
@ -1140,9 +1016,17 @@ ContainerState::ProcessDisplayItems(const nsDisplayList& aList,
nsLayoutUtils::GetActiveScrolledRootFor(viewportFrame, mBuilder->ReferenceFrame());
}
nscolor uniformColor;
PRBool isUniform = item->IsUniform(mBuilder, &uniformColor);
PRBool isOpaque = item->IsOpaque(mBuilder);
nsIntRect opaqueRect;
if (isOpaque) {
opaqueRect = item->GetBounds(mBuilder).ToNearestPixels(appUnitsPerDevPixel);
}
nsRefPtr<ThebesLayer> thebesLayer =
FindThebesLayerFor(item, itemVisibleRect, itemDrawRect,
activeScrolledRoot);
FindThebesLayerFor(itemVisibleRect, itemDrawRect, activeScrolledRoot,
isOpaque ? &opaqueRect : nsnull,
isUniform ? &uniformColor : nsnull);
InvalidateForLayerChange(item, thebesLayer);
@ -1230,36 +1114,15 @@ FrameLayerBuilder::AddLayerDisplayItem(Layer* aLayer,
}
}
nscolor
FrameLayerBuilder::FindOpaqueColorCovering(nsDisplayListBuilder* aBuilder,
ThebesLayer* aLayer,
const nsRect& aRect)
{
ThebesLayerItemsEntry* entry = mThebesLayerItems.GetEntry(aLayer);
NS_ASSERTION(entry, "Must know about this layer!");
for (PRInt32 i = entry->mItems.Length() - 1; i >= 0; --i) {
nsDisplayItem* item = entry->mItems[i].mItem;
const nsRect& visible = item->GetVisibleRect();
if (!visible.Intersects(aRect))
continue;
nscolor color;
if (visible.Contains(aRect) && item->IsUniform(aBuilder, &color) &&
NS_GET_A(color) == 255)
return color;
break;
}
return NS_RGBA(0,0,0,0);
}
void
ContainerState::CollectOldLayers()
{
for (Layer* layer = mContainerLayer->GetFirstChild(); layer;
layer = layer->GetNextSibling()) {
if (layer->HasUserData(&gColorLayerUserData)) {
void* data = layer->GetUserData();
if (data == &gColorLayerUserData) {
mRecycledColorLayers.AppendElement(static_cast<ColorLayer*>(layer));
} else if (layer->HasUserData(&gThebesDisplayItemLayerUserData)) {
} else if (data == &gThebesDisplayItemLayerUserData) {
NS_ASSERTION(layer->AsThebesLayer(), "Wrong layer type");
mRecycledThebesLayers.AppendElement(static_cast<ThebesLayer*>(layer));
}
@ -1340,7 +1203,7 @@ FrameLayerBuilder::BuildContainerLayerFor(nsDisplayListBuilder* aBuilder,
Layer* oldLayer = GetOldLayerFor(aContainerFrame, containerDisplayItemKey);
if (oldLayer) {
NS_ASSERTION(oldLayer->Manager() == aManager, "Wrong manager");
if (oldLayer->HasUserData(&gThebesDisplayItemLayerUserData)) {
if (oldLayer->GetUserData() == &gThebesDisplayItemLayerUserData) {
// The old layer for this item is actually our ThebesLayer
// because we rendered its layer into that ThebesLayer. So we
// don't actually have a retained container layer.
@ -1396,8 +1259,7 @@ FrameLayerBuilder::BuildContainerLayerFor(nsDisplayListBuilder* aBuilder,
state.ProcessDisplayItems(aChildren, nsnull);
state.Finish();
PRUint32 flags = aChildren.IsOpaque() ? Layer::CONTENT_OPAQUE : 0;
containerLayer->SetContentFlags(flags);
containerLayer->SetIsOpaqueContent(aChildren.IsOpaque());
return containerLayer.forget();
}
@ -1414,7 +1276,7 @@ FrameLayerBuilder::GetLeafLayerFor(nsDisplayListBuilder* aBuilder,
Layer* layer = GetOldLayerFor(f, aItem->GetPerFrameKey());
if (!layer)
return nsnull;
if (layer->HasUserData(&gThebesDisplayItemLayerUserData)) {
if (layer->GetUserData() == &gThebesDisplayItemLayerUserData) {
// This layer was created to render Thebes-rendered content for this
// display item. The display item should not use it for its own
// layer rendering.
@ -1490,7 +1352,7 @@ FrameLayerBuilder::InvalidateThebesLayersInSubtree(nsIFrame* aFrame)
FrameLayerBuilder::InvalidateAllThebesLayerContents(LayerManager* aManager)
{
LayerManagerData* data = static_cast<LayerManagerData*>
(aManager->GetUserData(&gLayerManagerUserData));
(aManager->GetUserData());
if (data) {
data->mInvalidateAllThebesContent = PR_TRUE;
}
@ -1500,7 +1362,7 @@ FrameLayerBuilder::InvalidateAllThebesLayerContents(LayerManager* aManager)
FrameLayerBuilder::InvalidateAllLayers(LayerManager* aManager)
{
LayerManagerData* data = static_cast<LayerManagerData*>
(aManager->GetUserData(&gLayerManagerUserData));
(aManager->GetUserData());
if (data) {
data->mInvalidateAllLayers = PR_TRUE;
}
@ -1518,9 +1380,9 @@ FrameLayerBuilder::HasDedicatedLayer(nsIFrame* aFrame, PRUint32 aDisplayItemKey)
(reinterpret_cast<nsTArray<DisplayItemData>*>(&propValue));
for (PRUint32 i = 0; i < array->Length(); ++i) {
if (array->ElementAt(i).mDisplayItemKey == aDisplayItemKey) {
Layer* layer = array->ElementAt(i).mLayer;
if (!layer->HasUserData(&gColorLayerUserData) &&
!layer->HasUserData(&gThebesDisplayItemLayerUserData))
void* layerUserData = array->ElementAt(i).mLayer->GetUserData();
if (layerUserData != &gColorLayerUserData &&
layerUserData != &gThebesDisplayItemLayerUserData)
return PR_TRUE;
}
}
@ -1549,15 +1411,6 @@ FrameLayerBuilder::DrawThebesLayer(ThebesLayer* aLayer,
// so 'entry' could become invalid.
}
ThebesDisplayItemLayerUserData* userData =
static_cast<ThebesDisplayItemLayerUserData*>
(aLayer->GetUserData(&gThebesDisplayItemLayerUserData));
NS_ASSERTION(userData, "where did our user data go?");
if (NS_GET_A(userData->mForcedBackgroundColor) > 0) {
aContext->SetColor(gfxRGBA(userData->mForcedBackgroundColor));
aContext->Paint();
}
gfxMatrix transform;
if (!aLayer->GetTransform().Is2D(&transform)) {
NS_ERROR("non-2D transform in our Thebes layer!");

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

@ -243,26 +243,6 @@ public:
*/
Layer* GetOldLayerFor(nsIFrame* aFrame, PRUint32 aDisplayItemKey);
/**
* A useful hashtable iteration function that removes the
* DisplayItemData property for the frame, clears its
* NS_FRAME_HAS_CONTAINER_LAYER bit and returns PL_DHASH_REMOVE.
* aClosure is ignored.
*/
static PLDHashOperator RemoveDisplayItemDataForFrame(nsPtrHashKey<nsIFrame>* aEntry,
void* aClosure)
{
return UpdateDisplayItemDataForFrame(aEntry, nsnull);
}
/**
* Try to determine whether the ThebesLayer aLayer paints an opaque
* single color everywhere it's visible in aRect.
* If successful, return that color, otherwise return NS_RGBA(0,0,0,0).
*/
nscolor FindOpaqueColorCovering(nsDisplayListBuilder* aBuilder,
ThebesLayer* aLayer, const nsRect& aRect);
protected:
/**
* We store an array of these for each frame that is associated with

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

@ -1251,9 +1251,9 @@ IsSmoothScrollingEnabled()
class ScrollFrameActivityTracker : public nsExpirationTracker<nsGfxScrollFrameInner,4> {
public:
// Wait for 3-4s between scrolls before we remove our layers.
// That's 4 generations of 1s each.
enum { TIMEOUT_MS = 1000 };
// Wait for 75-100ms between scrolls before we switch the appearance back to
// subpixel AA. That's 4 generations of 25ms each.
enum { TIMEOUT_MS = 25 };
ScrollFrameActivityTracker()
: nsExpirationTracker<nsGfxScrollFrameInner,4>(TIMEOUT_MS) {}
~ScrollFrameActivityTracker() {

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

@ -6,6 +6,6 @@
</head>
<body>
<marquee scrollamount="0" behavior="alternate" direction="right">&#x05E2;&#x05D3; &#x05E9;&#x05D9;&#x05E4;&#x05D5;&#x05D7; &#x05D4;&#x05D9;&#x05D5;&#x05DD; &#x05D5;&#x05E0;&#x05E1;&#x05D5; &#x05D4;&#x05E6;&#x05DC;&#x05D9;&#x05DC;&#x05D9;&#x05DD;</marquee>
<marquee scrollamount="0" behavior="alternate" direction="right" style="opacity:0.9">&#x05E2;&#x05D3; &#x05E9;&#x05D9;&#x05E4;&#x05D5;&#x05D7; &#x05D4;&#x05D9;&#x05D5;&#x05DD; &#x05D5;&#x05E0;&#x05E1;&#x05D5; &#x05D4;&#x05E6;&#x05DC;&#x05D9;&#x05DC;&#x05D9;&#x05DD;</marquee>
</body>
</html>

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

@ -6,6 +6,6 @@
</head>
<body>
<div dir="rtl" align="left">&#x05E2;&#x05D3; &#x05E9;&#x05D9;&#x05E4;&#x05D5;&#x05D7; &#x05D4;&#x05D9;&#x05D5;&#x05DD; &#x05D5;&#x05E0;&#x05E1;&#x05D5; &#x05D4;&#x05E6;&#x05DC;&#x05D9;&#x05DC;&#x05D9;&#x05DD;</div>
<div dir="rtl" align="left" style="opacity:0.9">&#x05E2;&#x05D3; &#x05E9;&#x05D9;&#x05E4;&#x05D5;&#x05D7; &#x05D4;&#x05D9;&#x05D5;&#x05DD; &#x05D5;&#x05E0;&#x05E1;&#x05D5; &#x05D4;&#x05E6;&#x05DC;&#x05D9;&#x05DC;&#x05D9;&#x05DD;</div>
</body>
</html>

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

@ -6,6 +6,6 @@
</head>
<body>
<marquee scrollamount="0" behavior="alternate" direction="right">&#x05DD;&#x05D9;&#x05DC;&#x05D9;&#x05DC;&#x05E6;&#x05D4; &#x05D5;&#x05E1;&#x05E0;&#x05D5; &#x05DD;&#x05D5;&#x05D9;&#x05D4; &#x05D7;&#x05D5;&#x05E4;&#x05D9;&#x05E9; &#x05D3;&#x05E2;</marquee>
<marquee scrollamount="0" behavior="alternate" direction="right" style="opacity:0.9">&#x05DD;&#x05D9;&#x05DC;&#x05D9;&#x05DC;&#x05E6;&#x05D4; &#x05D5;&#x05E1;&#x05E0;&#x05D5; &#x05DD;&#x05D5;&#x05D9;&#x05D4; &#x05D7;&#x05D5;&#x05E4;&#x05D9;&#x05E9; &#x05D3;&#x05E2;</marquee>
</body>
</html>

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

@ -4,7 +4,7 @@
<body>
<div style="background-color: lime; width: 600px; float:left;">
<div style="margin: 100px 0px; padding-left: 2px;">text</div>
<div style="margin: 100px 0px; padding-left: 2px; opacity:0.9;">text</div>
</div>
</body></html>

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

@ -8,7 +8,7 @@
<!-- padding-left used to avoid risk of an antialiasing pixel that may
project to the left of the origin, causing a spurious test failure
(see bugs 476927, 475968) -->
<div style="margin: 100px 0px; padding-left: 2px;">text</div>
<div style="margin: 100px 0px; padding-left: 2px; opacity:0.9;">text</div>
</div>
</marquee>

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

@ -1,7 +0,0 @@
<!DOCTYPE HTML>
<html>
<body style="height:2000px; overflow:hidden; background:url(repeatable-diagonal-gradient.png) fixed;">
<script src="scrolling.js"></script>
<p>Hello Kitty
</body>
</html>

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

@ -1,7 +1,5 @@
HTTP == fixed-1.html fixed-1.html?ref
HTTP == fixed-text-1.html fixed-text-1.html?ref
HTTP == opacity-mixed-scrolling-1.html opacity-mixed-scrolling-1.html?ref
HTTP == simple-1.html simple-1.html?ref
HTTP == text-1.html text-1.html?ref
== uncovering-1.html uncovering-1-ref.html
== uncovering-2.html uncovering-2-ref.html

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

@ -1,10 +0,0 @@
<!DOCTYPE HTML>
<html>
<body>
<script src="scrolling.js"></script>
<div class="scrollTop" style="height:100px; overflow:auto;">
<div style="margin-top:30px;">Hello Kitty</div>
<div style="height:400px;"></div>
</div>
</body>
</html>