зеркало из https://github.com/mozilla/gecko-dev.git
Backing out bug 579276. a=me
This commit is contained in:
Родитель
df7ddc69f9
Коммит
cfb7f48514
|
@ -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">עד שיפוח היום ונסו הצלילים</marquee>
|
||||
<marquee scrollamount="0" behavior="alternate" direction="right" style="opacity:0.9">עד שיפוח היום ונסו הצלילים</marquee>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -6,6 +6,6 @@
|
|||
</head>
|
||||
|
||||
<body>
|
||||
<div dir="rtl" align="left">עד שיפוח היום ונסו הצלילים</div>
|
||||
<div dir="rtl" align="left" style="opacity:0.9">עד שיפוח היום ונסו הצלילים</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -6,6 +6,6 @@
|
|||
</head>
|
||||
|
||||
<body>
|
||||
<marquee scrollamount="0" behavior="alternate" direction="right">םילילצה וסנו םויה חופיש דע</marquee>
|
||||
<marquee scrollamount="0" behavior="alternate" direction="right" style="opacity:0.9">םילילצה וסנו םויה חופיש דע</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>
|
Загрузка…
Ссылка в новой задаче