Bug 602200. Share code to compute effective transforms and opacity, and snap effective transforms. r=bas,sr=vlad,a=blocker

This commit is contained in:
Robert O'Callahan 2010-11-08 22:06:15 +13:00
Родитель bc736cccb8
Коммит 26f24119f8
54 изменённых файлов: 659 добавлений и 484 удалений

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

@ -207,6 +207,23 @@ public:
MOZ_LAYER_DECL_NAME("ImageLayer", TYPE_IMAGE)
virtual void ComputeEffectiveTransforms(const gfx3DMatrix& aTransformToSurface)
{
// Snap image edges to pixel boundaries
gfxRect snap(0, 0, 0, 0);
if (mContainer) {
gfxIntSize size = mContainer->GetCurrentSize();
snap.size = gfxSize(size.width, size.height);
}
// Snap our local transform first, and snap the inherited transform as well.
// This makes our snapping equivalent to what would happen if our content
// was drawn into a ThebesLayer (gfxContext would snap using the local
// transform, then we'd snap again when compositing the ThebesLayer).
mEffectiveTransform =
SnapTransform(GetLocalTransform(), snap, nsnull)*
SnapTransform(aTransformToSurface, gfxRect(0, 0, 0, 0), nsnull);
}
protected:
ImageLayer(LayerManager* aManager, void* aImplData)
: Layer(aManager, aImplData), mFilter(gfxPattern::FILTER_GOOD) {}

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

@ -226,23 +226,143 @@ Layer::GetEffectiveVisibleRegion()
return GetVisibleRegion();
}
const gfx3DMatrix&
Layer::GetEffectiveTransform()
{
if (ShadowLayer* shadow = AsShadowLayer()) {
return shadow->GetShadowTransform();
}
return GetTransform();
}
#else
const nsIntRect* Layer::GetEffectiveClipRect() { return GetClipRect(); }
const nsIntRegion& Layer::GetEffectiveVisibleRegion() { return GetVisibleRegion(); }
const gfx3DMatrix& Layer::GetEffectiveTransform() { return GetTransform(); }
#endif // MOZ_IPC
gfx3DMatrix
Layer::SnapTransform(const gfx3DMatrix& aTransform,
const gfxRect& aSnapRect,
gfxMatrix* aResidualTransform)
{
if (aResidualTransform) {
*aResidualTransform = gfxMatrix();
}
gfxMatrix matrix2D;
gfx3DMatrix result;
if (mManager->IsSnappingEffectiveTransforms() &&
aTransform.Is2D(&matrix2D) &&
matrix2D.HasNonIntegerTranslation() &&
!matrix2D.IsSingular() &&
!matrix2D.HasNonAxisAlignedTransform()) {
gfxMatrix snappedMatrix;
gfxPoint topLeft = matrix2D.Transform(aSnapRect.TopLeft());
topLeft.Round();
// first compute scale factors that scale aSnapRect to the snapped rect
if (aSnapRect.IsEmpty()) {
snappedMatrix.xx = matrix2D.xx;
snappedMatrix.yy = matrix2D.yy;
} else {
gfxPoint bottomRight = matrix2D.Transform(aSnapRect.BottomRight());
bottomRight.Round();
snappedMatrix.xx = (bottomRight.x - topLeft.x)/aSnapRect.Width();
snappedMatrix.yy = (bottomRight.y - topLeft.y)/aSnapRect.Height();
}
// compute translation factors that will move aSnapRect to the snapped rect
// given those scale factors
snappedMatrix.x0 = topLeft.x - aSnapRect.pos.x*snappedMatrix.xx;
snappedMatrix.y0 = topLeft.y - aSnapRect.pos.y*snappedMatrix.yy;
result = gfx3DMatrix::From2D(snappedMatrix);
if (aResidualTransform && !snappedMatrix.IsSingular()) {
// set aResidualTransform so that aResidual * snappedMatrix == matrix2D.
// (i.e., appying snappedMatrix after aResidualTransform gives the
// ideal transform.
gfxMatrix snappedMatrixInverse = snappedMatrix;
snappedMatrixInverse.Invert();
*aResidualTransform = matrix2D * snappedMatrixInverse;
}
} else {
result = aTransform;
}
return result;
}
const gfx3DMatrix&
Layer::GetLocalTransform()
{
#ifdef MOZ_IPC
if (ShadowLayer* shadow = AsShadowLayer())
return shadow->GetShadowTransform();
#endif
return mTransform;
}
float
Layer::GetEffectiveOpacity()
{
float opacity = GetOpacity();
for (ContainerLayer* c = GetParent(); c && !c->UseIntermediateSurface();
c = c->GetParent()) {
opacity *= c->GetOpacity();
}
return opacity;
}
PRBool
ContainerLayer::HasMultipleChildren()
{
PRUint32 count = 0;
for (Layer* child = GetFirstChild(); child; child = child->GetNextSibling()) {
const nsIntRect *clipRect = child->GetEffectiveClipRect();
if (clipRect && clipRect->IsEmpty())
continue;
if (child->GetVisibleRegion().IsEmpty())
continue;
++count;
if (count > 1)
return PR_TRUE;
}
return PR_FALSE;
}
void
ContainerLayer::DefaultComputeEffectiveTransforms(const gfx3DMatrix& aTransformToSurface)
{
gfxMatrix residual;
gfx3DMatrix idealTransform = GetLocalTransform()*aTransformToSurface;
mEffectiveTransform = SnapTransform(idealTransform, gfxRect(0, 0, 0, 0), &residual);
PRBool useIntermediateSurface;
float opacity = GetEffectiveOpacity();
if (opacity != 1.0f && HasMultipleChildren()) {
useIntermediateSurface = PR_TRUE;
} else {
useIntermediateSurface = PR_FALSE;
if (!mEffectiveTransform.IsIdentity()) {
for (Layer* child = GetFirstChild(); child; child = child->GetNextSibling()) {
const nsIntRect *clipRect = child->GetEffectiveClipRect();
/* We can't (easily) forward our transform to children with a non-empty clip
* rect since it would need to be adjusted for the transform.
* TODO: This is easily solvable for translation/scaling transforms.
*/
if (clipRect && !clipRect->IsEmpty() && !child->GetVisibleRegion().IsEmpty()) {
useIntermediateSurface = PR_TRUE;
break;
}
}
}
}
mUseIntermediateSurface = useIntermediateSurface;
if (useIntermediateSurface) {
ComputeEffectiveTransformsForChildren(gfx3DMatrix::From2D(residual));
} else {
ComputeEffectiveTransformsForChildren(idealTransform);
}
}
void
ContainerLayer::ComputeEffectiveTransformsForChildren(const gfx3DMatrix& aTransformToSurface)
{
for (Layer* l = mFirstChild; l; l = l->GetNextSibling()) {
l->ComputeEffectiveTransforms(aTransformToSurface);
}
}
#ifdef MOZ_LAYERS_HAVE_LOG

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

@ -229,7 +229,7 @@ public:
LAYERS_D3D10
};
LayerManager() : mDestroyed(PR_FALSE)
LayerManager() : mDestroyed(PR_FALSE), mSnapEffectiveTransforms(PR_TRUE)
{
InitLog();
}
@ -300,6 +300,8 @@ public:
virtual void EndTransaction(DrawThebesLayerCallback aCallback,
void* aCallbackData) = 0;
PRBool IsSnappingEffectiveTransforms() { return mSnapEffectiveTransforms; }
/**
* CONSTRUCTION PHASE ONLY
* Set the root layer.
@ -425,6 +427,7 @@ protected:
nsRefPtr<Layer> mRoot;
LayerUserDataSet mUserData;
PRPackedBool mDestroyed;
PRPackedBool mSnapEffectiveTransforms;
// Print interesting information about this into aTo. Internally
// used to implement Dump*() and Log*().
@ -655,7 +658,33 @@ public:
// accounting for this layer possibly being a shadow.
const nsIntRect* GetEffectiveClipRect();
const nsIntRegion& GetEffectiveVisibleRegion();
const gfx3DMatrix& GetEffectiveTransform();
/**
* Returns the product of the opacities of this layer and all ancestors up
* to and excluding the nearest ancestor that has UseIntermediateSurface() set.
*/
float GetEffectiveOpacity();
/**
* This returns the effective transform computed by
* ComputeEffectiveTransforms. Typically this is a transform that transforms
* this layer all the way to some intermediate surface or destination
* surface. For non-BasicLayers this will be a transform to the nearest
* ancestor with UseIntermediateSurface() (or to the root, if there is no
* such ancestor), but for BasicLayers it's different.
*/
const gfx3DMatrix& GetEffectiveTransform() const { return mEffectiveTransform; }
/**
* @param aTransformToSurface the composition of the transforms
* from the parent layer (if any) to the destination pixel grid.
*
* Computes mEffectiveTransform for this layer and all its descendants.
* mEffectiveTransform transforms this layer up to the destination
* pixel grid (whatever aTransformToSurface is relative to).
*
* We promise that when this is called on a layer, all ancestor layers
* have already had ComputeEffectiveTransforms called.
*/
virtual void ComputeEffectiveTransforms(const gfx3DMatrix& aTransformToSurface) = 0;
virtual const char* Name() const =0;
virtual LayerType GetType() const =0;
@ -719,6 +748,27 @@ protected:
// appends additional info to aTo.
virtual nsACString& PrintInfo(nsACString& aTo, const char* aPrefix);
/**
* Returns the local transform for this layer: either mTransform or,
* for shadow layers, GetShadowTransform()
*/
const gfx3DMatrix& GetLocalTransform();
/**
* Computes a tweaked version of aTransform that snaps a point or a rectangle
* to pixel boundaries. Snapping is only performed if this layer's
* layer manager has enabled snapping (which is the default).
* @param aSnapRect a rectangle whose edges should be snapped to pixel
* boundaries in the destination surface. If the rectangle is empty,
* then the snapping process should preserve the scale factors of the
* transform matrix
* @param aResidualTransform a transform to apply before mEffectiveTransform
* in order to get the results to completely match aTransform
*/
gfx3DMatrix SnapTransform(const gfx3DMatrix& aTransform,
const gfxRect& aSnapRect,
gfxMatrix* aResidualTransform);
LayerManager* mManager;
ContainerLayer* mParent;
Layer* mNextSibling;
@ -727,6 +777,7 @@ protected:
LayerUserDataSet mUserData;
nsIntRegion mVisibleRegion;
gfx3DMatrix mTransform;
gfx3DMatrix mEffectiveTransform;
float mOpacity;
nsIntRect mClipRect;
PRUint32 mContentFlags;
@ -765,6 +816,13 @@ public:
MOZ_LAYER_DECL_NAME("ThebesLayer", TYPE_THEBES)
virtual void ComputeEffectiveTransforms(const gfx3DMatrix& aTransformToSurface)
{
// The default implementation just snaps 0,0 to pixels.
gfx3DMatrix idealTransform = GetLocalTransform()*aTransformToSurface;
mEffectiveTransform = SnapTransform(idealTransform, gfxRect(0, 0, 0, 0), nsnull);
}
protected:
ThebesLayer(LayerManager* aManager, void* aImplData)
: Layer(aManager, aImplData)
@ -831,16 +889,50 @@ public:
MOZ_LAYER_DECL_NAME("ContainerLayer", TYPE_CONTAINER)
/**
* ContainerLayer backends need to override ComputeEffectiveTransforms
* since the decision about whether to use a temporary surface for the
* container is backend-specific. ComputeEffectiveTransforms must also set
* mUseIntermediateSurface.
*/
virtual void ComputeEffectiveTransforms(const gfx3DMatrix& aTransformToSurface) = 0;
/**
* Call this only after ComputeEffectiveTransforms has been invoked
* on this layer.
* Returns true if this will use an intermediate surface. This is largely
* backend-dependent, but it affects the operation of GetEffectiveOpacity().
*/
PRBool UseIntermediateSurface() { return mUseIntermediateSurface; }
/**
* Returns true if this container has more than one non-empty child
*/
PRBool HasMultipleChildren();
protected:
ContainerLayer(LayerManager* aManager, void* aImplData)
: Layer(aManager, aImplData),
mFirstChild(nsnull)
mFirstChild(nsnull),
mUseIntermediateSurface(PR_FALSE)
{}
/**
* A default implementation of ComputeEffectiveTransforms for use by OpenGL
* and D3D.
*/
void DefaultComputeEffectiveTransforms(const gfx3DMatrix& aTransformToSurface);
/**
* Loops over the children calling ComputeEffectiveTransforms on them.
*/
void ComputeEffectiveTransformsForChildren(const gfx3DMatrix& aTransformToSurface);
virtual nsACString& PrintInfo(nsACString& aTo, const char* aPrefix);
Layer* mFirstChild;
FrameMetrics mFrameMetrics;
PRPackedBool mUseIntermediateSurface;
};
/**
@ -864,6 +956,13 @@ public:
MOZ_LAYER_DECL_NAME("ColorLayer", TYPE_COLOR)
virtual void ComputeEffectiveTransforms(const gfx3DMatrix& aTransformToSurface)
{
// Snap 0,0 to pixel boundaries, no extra internal transform.
gfx3DMatrix idealTransform = GetLocalTransform()*aTransformToSurface;
mEffectiveTransform = SnapTransform(idealTransform, gfxRect(0, 0, 0, 0), nsnull);
}
protected:
ColorLayer(LayerManager* aManager, void* aImplData)
: Layer(aManager, aImplData),
@ -934,12 +1033,28 @@ public:
MOZ_LAYER_DECL_NAME("CanvasLayer", TYPE_CANVAS)
virtual void ComputeEffectiveTransforms(const gfx3DMatrix& aTransformToSurface)
{
// Snap our local transform first, and snap the inherited transform as well.
// This makes our snapping equivalent to what would happen if our content
// was drawn into a ThebesLayer (gfxContext would snap using the local
// transform, then we'd snap again when compositing the ThebesLayer).
mEffectiveTransform =
SnapTransform(GetLocalTransform(), gfxRect(0, 0, mBounds.width, mBounds.height),
nsnull)*
SnapTransform(aTransformToSurface, gfxRect(0, 0, 0, 0), nsnull);
}
protected:
CanvasLayer(LayerManager* aManager, void* aImplData)
: Layer(aManager, aImplData), mFilter(gfxPattern::FILTER_GOOD) {}
virtual nsACString& PrintInfo(nsACString& aTo, const char* aPrefix);
/**
* 0, 0, canvaswidth, canvasheight
*/
nsIntRect mBounds;
gfxPattern::GraphicsFilter mFilter;
};

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

@ -108,8 +108,7 @@ public:
*/
virtual void Paint(gfxContext* aContext,
LayerManager::DrawThebesLayerCallback aCallback,
void* aCallbackData,
float aOpacity) {}
void* aCallbackData) {}
virtual ShadowableLayer* AsShadowableLayer() { return nsnull; }
@ -174,6 +173,25 @@ public:
ContainerRemoveChild(aChild, this);
}
virtual void ComputeEffectiveTransforms(const gfx3DMatrix& aTransformToSurface)
{
// We push groups for container layers if we need to, which always
// are aligned in device space, so it doesn't really matter how we snap
// containers.
gfx3DMatrix idealTransform = GetLocalTransform()*aTransformToSurface;
mEffectiveTransform = SnapTransform(idealTransform, gfxRect(0, 0, 0, 0), nsnull);
// We always pass the ideal matrix down to our children, so there is no
// need to apply any compensation using the residual from SnapTransform.
ComputeEffectiveTransformsForChildren(idealTransform);
/* If we have a single child, it can just inherit our opacity,
* otherwise we need a PushGroup and we need to mark ourselves as using
* an intermediate surface so our children don't inherit our opacity
* via GetEffectiveOpacity.
*/
mUseIntermediateSurface = GetEffectiveOpacity() != 1.0 && HasMultipleChildren();
}
protected:
BasicLayerManager* BasicManager()
{
@ -344,8 +362,7 @@ public:
virtual void Paint(gfxContext* aContext,
LayerManager::DrawThebesLayerCallback aCallback,
void* aCallbackData,
float aOpacity);
void* aCallbackData);
virtual void ClearCachedResources() { mBuffer.Clear(); mValidRegion.SetEmpty(); }
@ -446,8 +463,7 @@ IntersectWithClip(const nsIntRegion& aRegion, gfxContext* aContext)
void
BasicThebesLayer::Paint(gfxContext* aContext,
LayerManager::DrawThebesLayerCallback aCallback,
void* aCallbackData,
float aOpacity)
void* aCallbackData)
{
NS_ASSERTION(BasicManager()->InDrawing(),
"Can only draw in drawing phase");
@ -461,9 +477,10 @@ BasicThebesLayer::Paint(gfxContext* aContext,
Buffer::ContentType contentType =
opaqueBuffer ? gfxASurface::CONTENT_COLOR :
gfxASurface::CONTENT_COLOR_ALPHA;
float opacity = GetEffectiveOpacity();
if (!BasicManager()->IsRetained() ||
(aOpacity == 1.0 && !canUseOpaqueSurface &&
(opacity == 1.0 && !canUseOpaqueSurface &&
!ShouldRetainTransparentSurface(mContentFlags, targetSurface) &&
!MustRetainContent())) {
mValidRegion.SetEmpty();
@ -473,13 +490,13 @@ BasicThebesLayer::Paint(gfxContext* aContext,
if (!toDraw.IsEmpty()) {
target->Save();
gfxUtils::ClipToRegionSnapped(target, toDraw);
if (aOpacity != 1.0) {
if (opacity != 1.0) {
target->PushGroup(contentType);
}
aCallback(this, target, toDraw, nsIntRegion(), aCallbackData);
if (aOpacity != 1.0) {
if (opacity != 1.0) {
target->PopGroupToSource();
target->Paint(aOpacity);
target->Paint(opacity);
}
target->Restore();
}
@ -513,7 +530,7 @@ BasicThebesLayer::Paint(gfxContext* aContext,
}
}
mBuffer.DrawTo(this, canUseOpaqueSurface, target, aOpacity);
mBuffer.DrawTo(this, canUseOpaqueSurface, target, opacity);
}
static PRBool
@ -600,8 +617,7 @@ public:
virtual void Paint(gfxContext* aContext,
LayerManager::DrawThebesLayerCallback aCallback,
void* aCallbackData,
float aOpacity);
void* aCallbackData);
static void PaintContext(gfxPattern* aPattern,
const gfxIntSize& aSize,
@ -624,10 +640,10 @@ protected:
void
BasicImageLayer::Paint(gfxContext* aContext,
LayerManager::DrawThebesLayerCallback aCallback,
void* aCallbackData,
float aOpacity)
void* aCallbackData)
{
nsRefPtr<gfxPattern> dontcare = GetAndPaintCurrentImage(aContext, aOpacity);
nsRefPtr<gfxPattern> dontcare =
GetAndPaintCurrentImage(aContext, GetEffectiveOpacity());
}
already_AddRefed<gfxPattern>
@ -677,8 +693,9 @@ BasicImageLayer::PaintContext(gfxPattern* aPattern,
/* Draw RGB surface onto frame */
aContext->NewPath();
aContext->PixelSnappedRectangleAndSetPattern(
gfxRect(0, 0, aSize.width, aSize.height), aPattern);
// No need to snap here; our transform has already taken care of it.
aContext->Rectangle(gfxRect(0, 0, aSize.width, aSize.height));
aContext->SetPattern(aPattern);
if (aOpacity != 1.0) {
aContext->Save();
aContext->Clip();
@ -710,10 +727,9 @@ public:
virtual void Paint(gfxContext* aContext,
LayerManager::DrawThebesLayerCallback aCallback,
void* aCallbackData,
float aOpacity)
void* aCallbackData)
{
PaintColorTo(mColor, mOpacity, aContext);
PaintColorTo(mColor, GetEffectiveOpacity(), aContext);
}
static void PaintColorTo(gfxRGBA aColor, float aOpacity,
@ -759,8 +775,7 @@ public:
virtual void Updated(const nsIntRect& aRect);
virtual void Paint(gfxContext* aContext,
LayerManager::DrawThebesLayerCallback aCallback,
void* aCallbackData,
float aOpacity);
void* aCallbackData);
protected:
BasicLayerManager* BasicManager()
@ -772,7 +787,6 @@ protected:
nsRefPtr<mozilla::gl::GLContext> mGLContext;
PRUint32 mCanvasFramebuffer;
nsIntRect mBounds;
nsIntRect mUpdatedRect;
PRPackedBool mGLBufferIsPremultiplied;
@ -870,8 +884,7 @@ BasicCanvasLayer::Updated(const nsIntRect& aRect)
void
BasicCanvasLayer::Paint(gfxContext* aContext,
LayerManager::DrawThebesLayerCallback aCallback,
void* aCallbackData,
float aOpacity)
void* aCallbackData)
{
NS_ASSERTION(BasicManager()->InDrawing(),
"Can only draw in drawing phase");
@ -881,7 +894,6 @@ BasicCanvasLayer::Paint(gfxContext* aContext,
pat->SetFilter(mFilter);
pat->SetExtend(gfxPattern::EXTEND_PAD);
gfxRect r(0, 0, mBounds.width, mBounds.height);
gfxMatrix m;
if (mNeedsYFlip) {
m = aContext->CurrentMatrix();
@ -889,12 +901,16 @@ BasicCanvasLayer::Paint(gfxContext* aContext,
aContext->Scale(1.0, -1.0);
}
float opacity = GetEffectiveOpacity();
aContext->NewPath();
aContext->PixelSnappedRectangleAndSetPattern(r, pat);
if (aOpacity != 1.0) {
// No need to snap here; our transform is already set up to snap our rect
aContext->Rectangle(gfxRect(0, 0, mBounds.width, mBounds.height));
aContext->SetPattern(pat);
if (opacity != 1.0) {
aContext->Save();
aContext->Clip();
aContext->Paint(aOpacity);
aContext->Paint(opacity);
aContext->Restore();
} else {
aContext->Fill();
@ -1108,8 +1124,11 @@ BasicLayerManager::EndTransaction(DrawThebesLayerCallback aCallback,
&cachedSurfaceOffset);
}
PaintLayer(mRoot, aCallback, aCallbackData, mRoot->GetOpacity());
mSnapEffectiveTransforms =
!(mTarget->GetFlags() & gfxContext::FLAG_DISABLE_SNAPPING);
mRoot->ComputeEffectiveTransforms(gfx3DMatrix::From2D(mTarget->CurrentMatrix()));
PaintLayer(mRoot, aCallback, aCallbackData);
if (useDoubleBuffering) {
finalTarget->SetOperator(gfxContext::OPERATOR_SOURCE);
PopGroupWithCachedSurface(finalTarget, cachedSurfaceOffset);
@ -1138,87 +1157,69 @@ BasicLayerManager::SetRoot(Layer* aLayer)
mRoot = aLayer;
}
// Returns true if we need to save the state of the gfxContext when
// we start painting aLayer (and restore the state when we've finished
// painting aLayer)
static PRBool
NeedsState(Layer* aLayer)
{
return aLayer->GetEffectiveClipRect() != nsnull ||
!aLayer->GetEffectiveTransform().IsIdentity();
}
static inline int
GetChildCount(Layer *aLayer)
{
int count = 0;
for (Layer* child = aLayer->GetFirstChild(); child;
child = child->GetNextSibling()) {
count++;
}
return count;
}
void
BasicLayerManager::PaintLayer(Layer* aLayer,
DrawThebesLayerCallback aCallback,
void* aCallbackData,
float aOpacity)
void* aCallbackData)
{
PRBool needsGroup = aOpacity != 1.0;
PRBool needsSaveRestore = needsGroup || NeedsState(aLayer);
int children = GetChildCount(aLayer);
const nsIntRect* clipRect = aLayer->GetEffectiveClipRect();
const gfx3DMatrix& effectiveTransform = aLayer->GetEffectiveTransform();
PRBool needsGroup = aLayer->GetFirstChild() &&
static_cast<BasicContainerLayer*>(aLayer)->UseIntermediateSurface();
// If needsSaveRestore is false, we should still save and restore
// the CTM
PRBool needsSaveRestore = needsGroup || clipRect;
if (needsSaveRestore) {
gfxMatrix savedMatrix;
if (needsSaveRestore) {
mTarget->Save();
if (const nsIntRect* r = aLayer->GetEffectiveClipRect()) {
if (clipRect) {
mTarget->NewPath();
mTarget->Rectangle(gfxRect(r->x, r->y, r->width, r->height), PR_TRUE);
mTarget->Rectangle(gfxRect(clipRect->x, clipRect->y, clipRect->width, clipRect->height), PR_TRUE);
mTarget->Clip();
}
} else {
savedMatrix = mTarget->CurrentMatrix();
}
gfxMatrix transform;
// XXX we need to add some kind of 3D transform support, possibly
// using pixman?
NS_ASSERTION(aLayer->GetEffectiveTransform().Is2D(),
"Only 2D transforms supported currently");
aLayer->GetEffectiveTransform().Is2D(&transform);
mTarget->Multiply(transform);
gfxMatrix transform;
// XXX we need to add some kind of 3D transform support, possibly
// using pixman?
NS_ASSERTION(effectiveTransform.Is2D(),
"Only 2D transforms supported currently");
effectiveTransform.Is2D(&transform);
mTarget->SetMatrix(transform);
if (needsGroup && children > 1) {
// If we need to call PushGroup, we should clip to the smallest possible
// area first to minimize the size of the temporary surface.
ClipToContain(mTarget, aLayer->GetEffectiveVisibleRegion().GetBounds());
if (needsGroup) {
// If we need to call PushGroup, we should clip to the smallest possible
// area first to minimize the size of the temporary surface.
ClipToContain(mTarget, aLayer->GetEffectiveVisibleRegion().GetBounds());
gfxASurface::gfxContentType type = aLayer->CanUseOpaqueSurface()
? gfxASurface::CONTENT_COLOR : gfxASurface::CONTENT_COLOR_ALPHA;
mTarget->PushGroup(type);
}
gfxASurface::gfxContentType type = aLayer->CanUseOpaqueSurface()
? gfxASurface::CONTENT_COLOR : gfxASurface::CONTENT_COLOR_ALPHA;
mTarget->PushGroup(type);
}
/* Only paint ourself, or our children - This optimization relies on this! */
if (!children) {
ToData(aLayer)->Paint(mTarget, aCallback, aCallbackData, aOpacity);
Layer* child = aLayer->GetFirstChild();
if (!child) {
ToData(aLayer)->Paint(mTarget, aCallback, aCallbackData);
} else {
for (Layer* child = aLayer->GetFirstChild(); child;
child = child->GetNextSibling()) {
/* If we have a single child, we can pass the aOpacity down, otherwise we will have double buffered */
if (needsGroup && children == 1) {
PaintLayer(child, aCallback, aCallbackData, child->GetOpacity() * aOpacity);
} else {
PaintLayer(child, aCallback, aCallbackData, child->GetOpacity());
}
for (; child; child = child->GetNextSibling()) {
PaintLayer(child, aCallback, aCallbackData);
}
}
if (needsSaveRestore) {
if (needsGroup && children > 1) {
mTarget->PopGroupToSource();
mTarget->Paint(aOpacity);
}
if (needsGroup) {
mTarget->PopGroupToSource();
mTarget->Paint(aLayer->GetEffectiveOpacity());
}
if (needsSaveRestore) {
mTarget->Restore();
} else {
mTarget->SetMatrix(savedMatrix);
}
}
@ -1591,8 +1592,7 @@ public:
virtual void Paint(gfxContext* aContext,
LayerManager::DrawThebesLayerCallback aCallback,
void* aCallbackData,
float aOpacity);
void* aCallbackData);
virtual void FillSpecificAttributes(SpecificLayerAttributes& aAttrs)
{
@ -1625,11 +1625,10 @@ private:
void
BasicShadowableImageLayer::Paint(gfxContext* aContext,
LayerManager::DrawThebesLayerCallback aCallback,
void* aCallbackData,
float aOpacity)
void* aCallbackData)
{
gfxIntSize oldSize = mSize;
nsRefPtr<gfxPattern> pat = GetAndPaintCurrentImage(aContext, aOpacity);
nsRefPtr<gfxPattern> pat = GetAndPaintCurrentImage(aContext, GetEffectiveOpacity());
if (!pat || !HasShadow())
return;
@ -1713,8 +1712,7 @@ public:
virtual void Initialize(const Data& aData);
virtual void Paint(gfxContext* aContext,
LayerManager::DrawThebesLayerCallback aCallback,
void* aCallbackData,
float aOpacity);
void* aCallbackData);
virtual void FillSpecificAttributes(SpecificLayerAttributes& aAttrs)
{
@ -1777,10 +1775,9 @@ BasicShadowableCanvasLayer::Initialize(const Data& aData)
void
BasicShadowableCanvasLayer::Paint(gfxContext* aContext,
LayerManager::DrawThebesLayerCallback aCallback,
void* aCallbackData,
float aOpacity)
void* aCallbackData)
{
BasicCanvasLayer::Paint(aContext, aCallback, aCallbackData, aOpacity);
BasicCanvasLayer::Paint(aContext, aCallback, aCallbackData);
if (!HasShadow())
return;
@ -1897,8 +1894,7 @@ public:
virtual void Paint(gfxContext* aContext,
LayerManager::DrawThebesLayerCallback aCallback,
void* aCallbackData,
float aOpacity);
void* aCallbackData);
private:
BasicShadowLayerManager* BasicManager()
@ -1987,8 +1983,7 @@ BasicShadowThebesLayer::Swap(const ThebesBuffer& aNewFront,
void
BasicShadowThebesLayer::Paint(gfxContext* aContext,
LayerManager::DrawThebesLayerCallback aCallback,
void* aCallbackData,
float aOpacity)
void* aCallbackData)
{
NS_ASSERTION(BasicManager()->InDrawing(),
"Can only draw in drawing phase");
@ -2002,13 +1997,7 @@ BasicShadowThebesLayer::Paint(gfxContext* aContext,
gfxContext* target = BasicManager()->GetTarget();
NS_ASSERTION(target, "We shouldn't be called if there's no target");
nsRefPtr<gfxASurface> targetSurface = aContext->CurrentSurface();
PRBool isOpaqueContent =
(targetSurface->AreSimilarSurfacesSensitiveToContentType() &&
aOpacity == 1.0 &&
CanUseOpaqueSurface());
mFrontBuffer.DrawTo(this, isOpaqueContent, target, aOpacity);
mFrontBuffer.DrawTo(this, CanUseOpaqueSurface(), target, GetEffectiveOpacity());
}
class BasicShadowContainerLayer : public ShadowContainerLayer, BasicImplData {
@ -2036,6 +2025,25 @@ public:
{ ContainerInsertAfter(aChild, aAfter, this); }
virtual void RemoveChild(Layer* aChild)
{ ContainerRemoveChild(aChild, this); }
virtual void ComputeEffectiveTransforms(const gfx3DMatrix& aTransformToSurface)
{
// We push groups for container layers if we need to, which always
// are aligned in device space, so it doesn't really matter how we snap
// containers.
gfx3DMatrix idealTransform = GetLocalTransform()*aTransformToSurface;
mEffectiveTransform = SnapTransform(idealTransform, gfxRect(0, 0, 0, 0), nsnull);
// We always pass the ideal matrix down to our children, so there is no
// need to apply any compensation using the residual from SnapTransform.
ComputeEffectiveTransformsForChildren(idealTransform);
/* If we have a single child, it can just inherit our opacity,
* otherwise we need a PushGroup and we need to mark ourselves as using
* an intermediate surface so our children don't inherit our opacity
* via GetEffectiveOpacity.
*/
mUseIntermediateSurface = GetEffectiveOpacity() != 1.0 && HasMultipleChildren();
}
};
class BasicShadowImageLayer : public ShadowImageLayer, BasicImplData {
@ -2071,8 +2079,7 @@ public:
virtual void Paint(gfxContext* aContext,
LayerManager::DrawThebesLayerCallback aCallback,
void* aCallbackData,
float aOpacity);
void* aCallbackData);
protected:
BasicShadowLayerManager* BasicManager()
@ -2105,8 +2112,7 @@ BasicShadowImageLayer::Swap(gfxSharedImageSurface* newFront)
void
BasicShadowImageLayer::Paint(gfxContext* aContext,
LayerManager::DrawThebesLayerCallback aCallback,
void* aCallbackData,
float aOpacity)
void* aCallbackData)
{
if (!mFrontSurface) {
return;
@ -2114,7 +2120,7 @@ BasicShadowImageLayer::Paint(gfxContext* aContext,
nsRefPtr<gfxPattern> pat = new gfxPattern(mFrontSurface);
pat->SetFilter(mFilter);
BasicImageLayer::PaintContext(pat, mSize, aOpacity, aContext);
BasicImageLayer::PaintContext(pat, mSize, GetEffectiveOpacity(), aContext);
}
class BasicShadowColorLayer : public ShadowColorLayer,
@ -2133,10 +2139,9 @@ public:
virtual void Paint(gfxContext* aContext,
LayerManager::DrawThebesLayerCallback aCallback,
void* aCallbackData,
float aOpacity)
void* aCallbackData)
{
BasicColorLayer::PaintColorTo(mColor, aOpacity, aContext);
BasicColorLayer::PaintColorTo(mColor, GetEffectiveOpacity(), aContext);
}
};
@ -2178,8 +2183,7 @@ public:
virtual void Paint(gfxContext* aContext,
LayerManager::DrawThebesLayerCallback aCallback,
void* aCallbackData,
float aOpacity);
void* aCallbackData);
private:
BasicShadowLayerManager* BasicManager()
@ -2188,7 +2192,6 @@ private:
}
nsRefPtr<gfxSharedImageSurface> mFrontSurface;
nsIntRect mBounds;
};
@ -2214,8 +2217,7 @@ BasicShadowCanvasLayer::Swap(gfxSharedImageSurface* newFront)
void
BasicShadowCanvasLayer::Paint(gfxContext* aContext,
LayerManager::DrawThebesLayerCallback aCallback,
void* aCallbackData,
float aOpacity)
void* aCallbackData)
{
NS_ASSERTION(BasicManager()->InDrawing(),
"Can only draw in drawing phase");
@ -2231,7 +2233,9 @@ BasicShadowCanvasLayer::Paint(gfxContext* aContext,
gfxRect r(0, 0, mBounds.width, mBounds.height);
aContext->NewPath();
aContext->PixelSnappedRectangleAndSetPattern(r, pat);
// No need to snap here; our transform has already taken care of it
aContext->Rectangle(r);
aContext->SetPattern(pat);
aContext->Fill();
}

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

@ -193,8 +193,7 @@ private:
// Paints aLayer to mTarget.
void PaintLayer(Layer* aLayer,
DrawThebesLayerCallback aCallback,
void* aCallbackData,
float aOpacity);
void* aCallbackData);
// Clear the contents of a layer
void ClearLayer(Layer* aLayer);

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

@ -202,7 +202,7 @@ CanvasLayerD3D10::GetLayer()
}
void
CanvasLayerD3D10::RenderLayer(float aOpacity, const gfx3DMatrix &aTransform)
CanvasLayerD3D10::RenderLayer()
{
if (!mTexture) {
return;
@ -210,9 +210,7 @@ CanvasLayerD3D10::RenderLayer(float aOpacity, const gfx3DMatrix &aTransform)
nsIntRect visibleRect = mVisibleRegion.GetBounds();
gfx3DMatrix transform = mTransform * aTransform;
effect()->GetVariableByName("mLayerTransform")->SetRawValue(&transform._11, 0, 64);
effect()->GetVariableByName("fLayerOpacity")->AsScalar()->SetFloat(GetOpacity() * aOpacity);
SetEffectTransformAndOpacity();
ID3D10EffectTechnique *technique;

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

@ -53,7 +53,6 @@ public:
CanvasLayerD3D10(LayerManagerD3D10 *aManager)
: CanvasLayer(aManager, NULL),
LayerD3D10(aManager),
mTexture(0),
mDataIsPremultiplied(PR_FALSE),
mNeedsYFlip(PR_FALSE)
{
@ -68,20 +67,17 @@ public:
// LayerD3D10 implementation
virtual Layer* GetLayer();
virtual void RenderLayer(float aOpacity, const gfx3DMatrix &aTransform);
virtual void RenderLayer();
private:
typedef mozilla::gl::GLContext GLContext;
nsRefPtr<gfxASurface> mSurface;
nsRefPtr<GLContext> mGLContext;
PRUint32 mCanvasFramebuffer;
nsRefPtr<ID3D10Texture2D> mTexture;
nsRefPtr<ID3D10ShaderResourceView> mSRView;
nsIntRect mBounds;
PRUint32 mCanvasFramebuffer;
PRPackedBool mDataIsPremultiplied;
PRPackedBool mNeedsYFlip;

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

@ -55,18 +55,19 @@ ColorLayerD3D10::GetLayer()
}
void
ColorLayerD3D10::RenderLayer(float aOpacity, const gfx3DMatrix &aTransform)
ColorLayerD3D10::RenderLayer()
{
float color[4];
// color is premultiplied, so we need to adjust all channels
color[0] = (float)(mColor.r * GetOpacity() * aOpacity);
color[1] = (float)(mColor.g * GetOpacity() * aOpacity);
color[2] = (float)(mColor.b * GetOpacity() * aOpacity);
color[3] = (float)(mColor.a * GetOpacity() * aOpacity);
float opacity = GetEffectiveOpacity();
color[0] = (float)(mColor.r * opacity);
color[1] = (float)(mColor.g * opacity);
color[2] = (float)(mColor.b * opacity);
color[3] = (float)(mColor.a * opacity);
gfx3DMatrix transform = mTransform * aTransform;
effect()->GetVariableByName("mLayerTransform")->SetRawValue(&transform._11, 0, 64);
const gfx3DMatrix& transform = GetEffectiveTransform();
void* raw = &const_cast<gfx3DMatrix&>(transform)._11;
effect()->GetVariableByName("mLayerTransform")->SetRawValue(raw, 0, 64);
effect()->GetVariableByName("fLayerColor")->AsVector()->SetFloatVector(color);
ID3D10EffectTechnique *technique;

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

@ -52,7 +52,7 @@ public:
/* LayerD3D10 implementation */
virtual Layer* GetLayer();
virtual void RenderLayer(float aOpacity, const gfx3DMatrix &aTransform);
virtual void RenderLayer();
};
} /* layers */

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

@ -136,14 +136,13 @@ ContainerLayerD3D10::GetFirstChildD3D10()
}
void
ContainerLayerD3D10::RenderLayer(float aOpacity, const gfx3DMatrix &aTransform)
ContainerLayerD3D10::RenderLayer()
{
float renderTargetOffset[] = { 0, 0 };
nsIntRect visibleRect = mVisibleRegion.GetBounds();
float opacity = GetOpacity() * aOpacity;
gfx3DMatrix transform = mTransform * aTransform;
PRBool useIntermediate = ShouldUseIntermediate(aOpacity, transform);
float opacity = GetEffectiveOpacity();
PRBool useIntermediate = UseIntermediateSurface();
nsRefPtr<ID3D10RenderTargetView> previousRTView;
nsRefPtr<ID3D10Texture2D> renderTexture;
@ -240,11 +239,7 @@ ContainerLayerD3D10::RenderLayer(float aOpacity, const gfx3DMatrix &aTransform)
}
// SetScissorRect
if (!useIntermediate) {
layerToRender->RenderLayer(opacity, transform);
} else {
layerToRender->RenderLayer(1.0f, gfx3DMatrix());
}
layerToRender->RenderLayer();
if (clipRect || useIntermediate) {
device()->RSSetScissorRects(1, &oldScissor);
@ -263,8 +258,7 @@ ContainerLayerD3D10::RenderLayer(float aOpacity, const gfx3DMatrix &aTransform)
effect()->GetVariableByName("vRenderTargetOffset")->
SetRawValue(previousRenderTargetOffset, 0, 8);
effect()->GetVariableByName("mLayerTransform")->SetRawValue(&transform._11, 0, 64);
effect()->GetVariableByName("fLayerOpacity")->AsScalar()->SetFloat(opacity);
SetEffectTransformAndOpacity();
ID3D10EffectTechnique *technique;
technique = effect()->GetTechniqueByName("RenderRGBALayerPremul");
@ -306,32 +300,5 @@ ContainerLayerD3D10::Validate()
}
}
bool
ContainerLayerD3D10::ShouldUseIntermediate(float aOpacity,
const gfx3DMatrix &aMatrix)
{
if (aOpacity == 1.0f && aMatrix.IsIdentity()) {
return false;
}
Layer *firstChild = GetFirstChild();
if (!firstChild || (!firstChild->GetNextSibling() &&
!firstChild->GetClipRect())) {
// If we forward our transform to a child without using an intermediate, we
// need to be sure that child does not have a clip rect since the clip rect
// needs to be applied after its transform.
return false;
}
if (aMatrix.IsIdentity() && (!firstChild || !firstChild->GetNextSibling())) {
// If there's no transforms applied and a single child, opacity can always
// be forwarded to our only child.
return false;
}
return true;
}
} /* layers */
} /* mozilla */

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

@ -63,13 +63,15 @@ public:
virtual LayerD3D10* GetFirstChildD3D10();
virtual void RenderLayer(float aOpacity, const gfx3DMatrix &aTransform);
virtual void RenderLayer();
virtual void Validate();
virtual void LayerManagerDestroyed();
private:
bool ShouldUseIntermediate(float aOpacity, const gfx3DMatrix &aTransform);
virtual void ComputeEffectiveTransforms(const gfx3DMatrix& aTransformToSurface)
{
DefaultComputeEffectiveTransforms(aTransformToSurface);
}
};
} /* layers */

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

@ -145,7 +145,7 @@ ImageLayerD3D10::GetLayer()
}
void
ImageLayerD3D10::RenderLayer(float aOpacity, const gfx3DMatrix &aTransform)
ImageLayerD3D10::RenderLayer()
{
if (!GetContainer()) {
return;
@ -153,10 +153,7 @@ ImageLayerD3D10::RenderLayer(float aOpacity, const gfx3DMatrix &aTransform)
nsRefPtr<Image> image = GetContainer()->GetCurrentImage();
gfx3DMatrix transform = mTransform * aTransform;
effect()->GetVariableByName("mLayerTransform")->SetRawValue(&transform._11, 0, 64);
effect()->GetVariableByName("fLayerOpacity")->AsScalar()->SetFloat(GetOpacity() * aOpacity);
SetEffectTransformAndOpacity();
ID3D10EffectTechnique *technique;

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

@ -88,7 +88,7 @@ public:
// LayerD3D10 Implementation
virtual Layer* GetLayer();
virtual void RenderLayer(float aOpacity, const gfx3DMatrix &aTransform);
virtual void RenderLayer();
};
class THEBES_API ImageD3D10

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

@ -236,6 +236,11 @@ LayerManagerD3D10::EndTransaction(DrawThebesLayerCallback aCallback,
{
mCurrentCallbackInfo.Callback = aCallback;
mCurrentCallbackInfo.CallbackData = aCallbackData;
// The results of our drawing always go directly into a pixel buffer,
// so we don't need to pass any global transform here.
mRoot->ComputeEffectiveTransforms(gfx3DMatrix());
Render();
mCurrentCallbackInfo.Callback = nsnull;
mCurrentCallbackInfo.CallbackData = nsnull;
@ -462,7 +467,7 @@ LayerManagerD3D10::Render()
}
device()->RSSetScissorRects(1, &r);
static_cast<LayerD3D10*>(mRoot->ImplData())->RenderLayer(1, gfx3DMatrix());
static_cast<LayerD3D10*>(mRoot->ImplData())->RenderLayer();
}
if (mTarget) {

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

@ -191,11 +191,9 @@ public:
/**
* This will render a child layer to whatever render target is currently
* active. aOpacity and aTransform will pass any 'carried' transformations
* and/or opacity from the parent. This allows the parent to avoid
* rendering to intermediate surfaces when possible.
* active.
*/
virtual void RenderLayer(float aOpacity, const gfx3DMatrix &aTransform) = 0;
virtual void RenderLayer() = 0;
virtual void Validate() {}
ID3D10Device1 *device() const { return mD3DManager->device(); }
@ -203,6 +201,16 @@ public:
/* Called by the layer manager when it's destroyed */
virtual void LayerManagerDestroyed() {}
void SetEffectTransformAndOpacity()
{
Layer* layer = GetLayer();
const gfx3DMatrix& transform = layer->GetEffectiveTransform();
void* raw = &const_cast<gfx3DMatrix&>(transform)._11;
effect()->GetVariableByName("mLayerTransform")->SetRawValue(raw, 0, 64);
effect()->GetVariableByName("fLayerOpacity")->AsScalar()->SetFloat(layer->GetEffectiveOpacity());
}
protected:
LayerManagerD3D10 *mD3DManager;
};

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

@ -152,7 +152,7 @@ ThebesLayerD3D10::InvalidateRegion(const nsIntRegion &aRegion)
}
void
ThebesLayerD3D10::RenderLayer(float aOpacity, const gfx3DMatrix &aTransform)
ThebesLayerD3D10::RenderLayer()
{
if (!mTexture) {
return;
@ -160,9 +160,7 @@ ThebesLayerD3D10::RenderLayer(float aOpacity, const gfx3DMatrix &aTransform)
nsIntRect visibleRect = mVisibleRegion.GetBounds();
gfx3DMatrix transform = mTransform * aTransform;
effect()->GetVariableByName("mLayerTransform")->SetRawValue(&transform._11, 0, 64);
effect()->GetVariableByName("fLayerOpacity")->AsScalar()->SetFloat(GetOpacity() * aOpacity);
SetEffectTransformAndOpacity();
ID3D10EffectTechnique *technique;
if (CanUseOpaqueSurface()) {

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

@ -59,7 +59,7 @@ public:
/* LayerD3D10 implementation */
virtual Layer* GetLayer();
virtual void RenderLayer(float aOpacity, const gfx3DMatrix &aTransform);
virtual void RenderLayer();
virtual void Validate();
virtual void LayerManagerDestroyed();

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

@ -227,7 +227,7 @@ CanvasLayerD3D9::GetLayer()
}
void
CanvasLayerD3D9::RenderLayer(float aOpacity, const gfx3DMatrix &aTransform)
CanvasLayerD3D9::RenderLayer()
{
if (!mTexture) {
Updated(mBounds);
@ -246,16 +246,7 @@ CanvasLayerD3D9::RenderLayer(float aOpacity, const gfx3DMatrix &aTransform)
device()->SetVertexShaderConstantF(CBvLayerQuad, quad, 1);
gfx3DMatrix transform = mTransform * aTransform;
device()->SetVertexShaderConstantF(CBmLayerTransform, &transform._11, 4);
float opacity[4];
/*
* We always upload a 4 component float, but the shader will use only the
* first component since it's declared as a 'float'.
*/
opacity[0] = GetOpacity();
device()->SetPixelShaderConstantF(CBfLayerOpacity, opacity, 1);
SetShaderTransformAndOpacity();
mD3DManager->SetShaderMode(DeviceManagerD3D9::RGBALAYER);

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

@ -54,7 +54,6 @@ public:
CanvasLayerD3D9(LayerManagerD3D9 *aManager)
: CanvasLayer(aManager, NULL),
LayerD3D9(aManager),
mTexture(0),
mDataIsPremultiplied(PR_FALSE),
mNeedsYFlip(PR_FALSE)
{
@ -70,7 +69,7 @@ public:
// LayerD3D9 implementation
virtual Layer* GetLayer();
virtual void RenderLayer(float aOpacity, const gfx3DMatrix &aTransform);
virtual void RenderLayer();
virtual void CleanResources();
virtual void LayerManagerDestroyed();
@ -79,17 +78,14 @@ public:
protected:
typedef mozilla::gl::GLContext GLContext;
// Indicates whether our texture was obtained through D2D interop.
bool mIsInteropTexture;
nsRefPtr<gfxASurface> mSurface;
nsRefPtr<GLContext> mGLContext;
nsRefPtr<IDirect3DTexture9> mTexture;
PRUint32 mCanvasFramebuffer;
nsRefPtr<IDirect3DTexture9> mTexture;
nsIntRect mBounds;
// Indicates whether our texture was obtained through D2D interop.
bool mIsInteropTexture;
PRPackedBool mDataIsPremultiplied;
PRPackedBool mNeedsYFlip;

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

@ -48,7 +48,7 @@ ColorLayerD3D9::GetLayer()
}
void
ColorLayerD3D9::RenderLayer(float aOpacity, const gfx3DMatrix &aTransform)
ColorLayerD3D9::RenderLayer()
{
// XXX we might be able to improve performance by using
// IDirect3DDevice9::Clear
@ -63,15 +63,16 @@ ColorLayerD3D9::RenderLayer(float aOpacity, const gfx3DMatrix &aTransform)
visibleRect.height),
1);
gfx3DMatrix transform = mTransform * aTransform;
const gfx3DMatrix& transform = GetEffectiveTransform();
device()->SetVertexShaderConstantF(CBmLayerTransform, &transform._11, 4);
float color[4];
float opacity = GetEffectiveOpacity();
// color is premultiplied, so we need to adjust all channels
color[0] = (float)(mColor.r * GetOpacity() * aOpacity);
color[1] = (float)(mColor.g * GetOpacity() * aOpacity);
color[2] = (float)(mColor.b * GetOpacity() * aOpacity);
color[3] = (float)(mColor.a * GetOpacity() * aOpacity);
color[0] = (float)(mColor.r * opacity);
color[1] = (float)(mColor.g * opacity);
color[2] = (float)(mColor.b * opacity);
color[3] = (float)(mColor.a * opacity);
device()->SetPixelShaderConstantF(0, color, 1);

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

@ -58,7 +58,7 @@ public:
// LayerD3D9 Implementation
virtual Layer* GetLayer();
virtual void RenderLayer(float aOpacity, const gfx3DMatrix &aTransform);
virtual void RenderLayer();
};
} /* layers */

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

@ -135,9 +135,8 @@ ContainerLayerD3D9::GetFirstChildD3D9()
}
void
ContainerLayerD3D9::RenderLayer(float aOpacity, const gfx3DMatrix &aTransform)
ContainerLayerD3D9::RenderLayer()
{
float opacity = GetOpacity() * aOpacity;
nsRefPtr<IDirect3DSurface9> previousRenderTarget;
nsRefPtr<IDirect3DTexture9> renderTexture;
float previousRenderTargetOffset[4];
@ -145,10 +144,8 @@ ContainerLayerD3D9::RenderLayer(float aOpacity, const gfx3DMatrix &aTransform)
float renderTargetOffset[] = { 0, 0, 0, 0 };
float oldViewMatrix[4][4];
gfx3DMatrix transform = mTransform * aTransform;
nsIntRect visibleRect = mVisibleRegion.GetBounds();
PRBool useIntermediate = ShouldUseIntermediate(opacity, transform);
PRBool useIntermediate = UseIntermediateSurface();
if (useIntermediate) {
device()->GetRenderTarget(0, getter_AddRefs(previousRenderTarget));
@ -223,11 +220,7 @@ ContainerLayerD3D9::RenderLayer(float aOpacity, const gfx3DMatrix &aTransform)
device()->SetScissorRect(&r);
}
if (!useIntermediate) {
layerToRender->RenderLayer(opacity, transform);
} else {
layerToRender->RenderLayer(1.0, gfx3DMatrix());
}
layerToRender->RenderLayer();
if (clipRect || useIntermediate) {
device()->SetScissorRect(&oldClipRect);
@ -251,15 +244,7 @@ ContainerLayerD3D9::RenderLayer(float aOpacity, const gfx3DMatrix &aTransform)
visibleRect.height),
1);
device()->SetVertexShaderConstantF(CBmLayerTransform, &transform._11, 4);
float opacityVector[4];
/*
* We always upload a 4 component float, but the shader will use only the
* first component since it's declared as a 'float'.
*/
opacityVector[0] = opacity;
device()->SetPixelShaderConstantF(CBfLayerOpacity, opacityVector, 1);
SetShaderTransformAndOpacity();
mD3DManager->SetShaderMode(DeviceManagerD3D9::RGBALAYER);
@ -277,32 +262,5 @@ ContainerLayerD3D9::LayerManagerDestroyed()
}
}
bool
ContainerLayerD3D9::ShouldUseIntermediate(float aOpacity,
const gfx3DMatrix &aMatrix)
{
if (aOpacity == 1.0f && aMatrix.IsIdentity()) {
return false;
}
Layer *firstChild = GetFirstChild();
if (!firstChild || (!firstChild->GetNextSibling() &&
!firstChild->GetClipRect())) {
// If we forward our transform to a child without using an intermediate,
// we need to be sure that child does not have a clip rect, since its clip
// rect would be applied after our transform.
return false;
}
if (aMatrix.IsIdentity() && (!firstChild || !firstChild->GetNextSibling())) {
// If there's no transforms applied and a single child, opacity can always
// be forwarded to our only child.
return false;
}
return true;
}
} /* layers */
} /* mozilla */

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

@ -65,13 +65,14 @@ public:
PRBool IsEmpty();
void RenderLayer(float aOpacity, const gfx3DMatrix &aTransform);
void RenderLayer();
virtual void LayerManagerDestroyed();
private:
bool ShouldUseIntermediate(float aOpacity,
const gfx3DMatrix &aMatrix);
virtual void ComputeEffectiveTransforms(const gfx3DMatrix& aTransformToSurface)
{
DefaultComputeEffectiveTransforms(aTransformToSurface);
}
};
} /* layers */

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

@ -148,7 +148,7 @@ ImageLayerD3D9::GetLayer()
}
void
ImageLayerD3D9::RenderLayer(float aOpacity, const gfx3DMatrix &aTransform)
ImageLayerD3D9::RenderLayer()
{
if (!GetContainer()) {
return;
@ -172,16 +172,7 @@ ImageLayerD3D9::RenderLayer(float aOpacity, const gfx3DMatrix &aTransform)
yuvImage->mSize.height),
1);
gfx3DMatrix transform = mTransform * aTransform;
device()->SetVertexShaderConstantF(CBmLayerTransform, &transform._11, 4);
float opacity[4];
/*
* We always upload a 4 component float, but the shader will
* only use the the first component since it's declared as a 'float'.
*/
opacity[0] = GetOpacity() * aOpacity;
device()->SetPixelShaderConstantF(CBfLayerOpacity, opacity, 1);
SetShaderTransformAndOpacity();
mD3DManager->SetShaderMode(DeviceManagerD3D9::YCBCRLAYER);
@ -221,16 +212,7 @@ ImageLayerD3D9::RenderLayer(float aOpacity, const gfx3DMatrix &aTransform)
cairoImage->mSize.height),
1);
gfx3DMatrix transform = mTransform * aTransform;
device()->SetVertexShaderConstantF(CBmLayerTransform, &transform._11, 4);
float opacity[4];
/*
* We always upload a 4 component float, but the shader will
* only use the the first component since it's declared as a 'float'.
*/
opacity[0] = GetOpacity() * aOpacity;
device()->SetPixelShaderConstantF(CBfLayerOpacity, opacity, 1);
SetShaderTransformAndOpacity();
mD3DManager->SetShaderMode(DeviceManagerD3D9::RGBALAYER);

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

@ -87,7 +87,7 @@ public:
// LayerD3D9 Implementation
virtual Layer* GetLayer();
virtual void RenderLayer(float aOpacity, const gfx3DMatrix &aTransform);
virtual void RenderLayer();
};
class THEBES_API ImageD3D9

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

@ -155,6 +155,11 @@ LayerManagerD3D9::EndTransaction(DrawThebesLayerCallback aCallback,
{
mCurrentCallbackInfo.Callback = aCallback;
mCurrentCallbackInfo.CallbackData = aCallbackData;
// The results of our drawing always go directly into a pixel buffer,
// so we don't need to pass any global transform here.
mRoot->ComputeEffectiveTransforms(gfx3DMatrix());
Render();
/* Clean this out for sanity */
mCurrentCallbackInfo.Callback = NULL;
@ -298,7 +303,7 @@ LayerManagerD3D9::Render()
}
device()->SetScissorRect(&r);
static_cast<LayerD3D9*>(mRoot->ImplData())->RenderLayer(1.0, gfx3DMatrix());
static_cast<LayerD3D9*>(mRoot->ImplData())->RenderLayer();
}
device()->EndScene();

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

@ -251,8 +251,9 @@ public:
virtual Layer* GetLayer() = 0;
virtual void RenderLayer(float aOpacity, const gfx3DMatrix &aTransform) = 0;
virtual void RenderLayer() = 0;
/**
/* This function may be used on device resets to clear all VRAM resources
* that a layer might be using.
*/
@ -266,6 +267,22 @@ public:
void ReportFailure(const nsACString &aMsg, HRESULT aCode) {
return mD3DManager->ReportFailure(aMsg, aCode);
}
void SetShaderTransformAndOpacity()
{
Layer* layer = GetLayer();
const gfx3DMatrix& transform = layer->GetEffectiveTransform();
device()->SetVertexShaderConstantF(CBmLayerTransform, &transform._11, 4);
float opacity[4];
/*
* We always upload a 4 component float, but the shader will use only the
* first component since it's declared as a 'float'.
*/
opacity[0] = layer->GetEffectiveOpacity();
device()->SetPixelShaderConstantF(CBfLayerOpacity, opacity, 1);
}
protected:
LayerManagerD3D9 *mD3DManager;
};

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

@ -172,7 +172,7 @@ ThebesLayerD3D9::InvalidateRegion(const nsIntRegion &aRegion)
}
void
ThebesLayerD3D9::RenderLayer(float aOpacity, const gfx3DMatrix &aTransform)
ThebesLayerD3D9::RenderLayer()
{
if (mVisibleRegion.IsEmpty()) {
return;
@ -225,16 +225,7 @@ ThebesLayerD3D9::RenderLayer(float aOpacity, const gfx3DMatrix &aTransform)
mValidRegion = mVisibleRegion;
}
gfx3DMatrix transform = mTransform * aTransform;
device()->SetVertexShaderConstantF(CBmLayerTransform, &transform._11, 4);
float opacity[4];
/*
* We always upload a 4 component float, but the shader will use only the
* first component since it's declared as a 'float'.
*/
opacity[0] = GetOpacity() * aOpacity;
device()->SetPixelShaderConstantF(0, opacity, 1);
SetShaderTransformAndOpacity();
#ifdef CAIRO_HAS_D2D_SURFACE
if (mD2DSurface && CanUseOpaqueSurface()) {

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

@ -61,7 +61,7 @@ public:
/* LayerD3D9 implementation */
Layer* GetLayer();
virtual PRBool IsEmpty();
virtual void RenderLayer(float aOpacity, const gfx3DMatrix &aTransform);
virtual void RenderLayer();
virtual void CleanResources();
virtual void LayerManagerDestroyed();

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

@ -231,9 +231,7 @@ CanvasLayerOGL::Updated(const nsIntRect& aRect)
void
CanvasLayerOGL::RenderLayer(int aPreviousDestination,
const nsIntPoint& aOffset,
float aOpacity,
const gfx3DMatrix& aMatrix)
const nsIntPoint& aOffset)
{
mOGLManager->MakeCurrent();
@ -268,8 +266,8 @@ CanvasLayerOGL::RenderLayer(int aPreviousDestination,
program->Activate();
program->SetLayerQuadRect(mBounds);
program->SetLayerTransform(GetEffectiveTransform() * aMatrix);
program->SetLayerOpacity(GetOpacity() * aOpacity);
program->SetLayerTransform(GetEffectiveTransform());
program->SetLayerOpacity(GetEffectiveOpacity());
program->SetRenderOffset(aOffset);
program->SetTextureUnit(0);
@ -354,9 +352,7 @@ ShadowCanvasLayerOGL::GetLayer()
void
ShadowCanvasLayerOGL::RenderLayer(int aPreviousFrameBuffer,
const nsIntPoint& aOffset,
float aOpacity,
const gfx3DMatrix& aMatrix)
const nsIntPoint& aOffset)
{
mOGLManager->MakeCurrent();
@ -370,8 +366,8 @@ ShadowCanvasLayerOGL::RenderLayer(int aPreviousFrameBuffer,
program->Activate();
program->SetLayerQuadRect(nsIntRect(nsIntPoint(0, 0), mTexImage->GetSize()));
program->SetLayerTransform(mTransform * aMatrix);
program->SetLayerOpacity(GetOpacity() * aOpacity);
program->SetLayerTransform(GetEffectiveTransform());
program->SetLayerOpacity(GetEffectiveOpacity());
program->SetRenderOffset(aOffset);
program->SetTextureUnit(0);

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

@ -71,9 +71,7 @@ public:
virtual void Destroy();
virtual Layer* GetLayer() { return this; }
virtual void RenderLayer(int aPreviousFrameBuffer,
const nsIntPoint& aOffset,
float aOpacity,
const gfx3DMatrix& aMatrix);
const nsIntPoint& aOffset);
protected:
nsRefPtr<gfxASurface> mCanvasSurface;
@ -82,7 +80,6 @@ protected:
void MakeTexture();
GLuint mTexture;
nsIntRect mBounds;
nsIntRect mUpdatedRect;
PRPackedBool mGLBufferIsPremultiplied;
@ -117,9 +114,7 @@ public:
void Destroy();
Layer* GetLayer();
virtual void RenderLayer(int aPreviousFrameBuffer,
const nsIntPoint& aOffset,
float aOpacity,
const gfx3DMatrix& aMatrix);
const nsIntPoint& aOffset);
private:
nsRefPtr<TextureImage> mTexImage;

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

@ -43,8 +43,7 @@ namespace layers {
static void
RenderColorLayer(ColorLayer* aLayer, LayerManagerOGL *aManager,
const nsIntPoint& aOffset, float aOpacity,
const gfx3DMatrix& aMatrix)
const nsIntPoint& aOffset)
{
aManager->MakeCurrent();
@ -57,7 +56,7 @@ RenderColorLayer(ColorLayer* aLayer, LayerManagerOGL *aManager,
* write to the color buffer. This saves a needless
* multiply in the fragment shader.
*/
float opacity = aLayer->GetOpacity() * aOpacity;
float opacity = aLayer->GetEffectiveOpacity();
gfxRGBA color(aLayer->GetColor());
color.r *= opacity;
color.g *= opacity;
@ -67,7 +66,7 @@ RenderColorLayer(ColorLayer* aLayer, LayerManagerOGL *aManager,
SolidColorLayerProgram *program = aManager->GetColorLayerProgram();
program->Activate();
program->SetLayerQuadRect(visibleRect);
program->SetLayerTransform(aLayer->GetEffectiveTransform() * aMatrix);
program->SetLayerTransform(aLayer->GetEffectiveTransform());
program->SetRenderOffset(aOffset);
program->SetRenderColor(color);
@ -78,21 +77,17 @@ RenderColorLayer(ColorLayer* aLayer, LayerManagerOGL *aManager,
void
ColorLayerOGL::RenderLayer(int,
const nsIntPoint& aOffset,
float aOpacity,
const gfx3DMatrix& aMatrix)
const nsIntPoint& aOffset)
{
return RenderColorLayer(this, mOGLManager, aOffset, aOpacity, aMatrix);
return RenderColorLayer(this, mOGLManager, aOffset);
}
#ifdef MOZ_IPC
void
ShadowColorLayerOGL::RenderLayer(int,
const nsIntPoint& aOffset,
float aOpacity,
const gfx3DMatrix& aMatrix)
const nsIntPoint& aOffset)
{
return RenderColorLayer(this, mOGLManager, aOffset, aOpacity, aMatrix);
return RenderColorLayer(this, mOGLManager, aOffset);
}
#endif // MOZ_IPC

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

@ -66,9 +66,7 @@ public:
virtual void Destroy() { mDestroyed = PR_TRUE; }
virtual void RenderLayer(int aPreviousFrameBuffer,
const nsIntPoint& aOffset,
float aOpacity,
const gfx3DMatrix& aMatrix);
const nsIntPoint& aOffset);
};
#ifdef MOZ_IPC
@ -90,9 +88,7 @@ public:
virtual void Destroy() { mDestroyed = PR_TRUE; }
virtual void RenderLayer(int aPreviousFrameBuffer,
const nsIntPoint& aOffset,
float aOpacity,
const gfx3DMatrix& aMatrix);
const nsIntPoint& aOffset);
};
#endif // MOZ_IPC

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

@ -120,49 +120,11 @@ ContainerDestroy(Container* aContainer)
}
}
template<class Container>
static bool
ShouldUseIntermediate(Container* aContainer,
float aOpacity,
const gfx3DMatrix& aMatrix)
{
if (aOpacity == 1.0f && aMatrix.IsIdentity()) {
return false;
}
Layer *firstChild = aContainer->GetFirstChild();
if (!firstChild) {
return false;
}
/* We always require an intermediate layer for opacity */
if (aOpacity != 1.0f) {
return true;
}
do {
const nsIntRect *clipRect = firstChild->GetClipRect();
/* We can't (easily) forward our transform to children with a non-emtpy clip
* rect since it would need to be adjusted for the transform.
* TODO: This is easily solvable for translation/scaling transforms.
*/
if (clipRect && !clipRect->IsEmpty() && !firstChild->GetVisibleRegion().IsEmpty()) {
return true;
}
} while ((firstChild = firstChild->GetNextSibling()) != nsnull);
/* All children have no clip or are invisible */
return false;
}
template<class Container>
static void
ContainerRender(Container* aContainer,
int aPreviousFrameBuffer,
const nsIntPoint& aOffset,
float aOpacity,
const gfx3DMatrix& aMatrix,
LayerManagerOGL* aManager)
{
/**
@ -173,13 +135,13 @@ ContainerRender(Container* aContainer,
nsIntPoint childOffset(aOffset);
nsIntRect visibleRect = aContainer->GetEffectiveVisibleRegion().GetBounds();
const gfx3DMatrix& transform = aContainer->GetEffectiveTransform() * aMatrix;
nsIntRect cachedScissor = aContainer->gl()->ScissorRect();
aContainer->gl()->PushScissorRect();
float opacity = aContainer->GetOpacity() * aOpacity;
bool needsFramebuffer = ShouldUseIntermediate(aContainer, opacity, transform);
float opacity = aContainer->GetEffectiveOpacity();
const gfx3DMatrix& transform = aContainer->GetEffectiveTransform();
bool needsFramebuffer = aContainer->UseIntermediateSurface();
if (needsFramebuffer) {
aManager->CreateFBOWithTexture(visibleRect.width,
visibleRect.height,
@ -237,11 +199,7 @@ ContainerRender(Container* aContainer,
cachedScissor.height);
}
if (!needsFramebuffer) {
layerToRender->RenderLayer(frameBuffer, childOffset, opacity, transform);
} else {
layerToRender->RenderLayer(frameBuffer, childOffset, 1.0, gfx3DMatrix());
}
layerToRender->RenderLayer(frameBuffer, childOffset);
Layer *nextSibling = layerToRender->GetLayer()->GetNextSibling();
layerToRender = nextSibling ? static_cast<LayerOGL*>(nextSibling->
@ -336,11 +294,9 @@ ContainerLayerOGL::GetFirstChildOGL()
void
ContainerLayerOGL::RenderLayer(int aPreviousFrameBuffer,
const nsIntPoint& aOffset,
float aOpacity,
const gfx3DMatrix& aMatrix)
const nsIntPoint& aOffset)
{
ContainerRender(this, aPreviousFrameBuffer, aOffset, aOpacity, aMatrix, mOGLManager);
ContainerRender(this, aPreviousFrameBuffer, aOffset, mOGLManager);
}
@ -387,11 +343,9 @@ ShadowContainerLayerOGL::GetFirstChildOGL()
void
ShadowContainerLayerOGL::RenderLayer(int aPreviousFrameBuffer,
const nsIntPoint& aOffset,
float aOpacity,
const gfx3DMatrix& aMatrix)
const nsIntPoint& aOffset)
{
ContainerRender(this, aPreviousFrameBuffer, aOffset, aOpacity, aMatrix, mOGLManager);
ContainerRender(this, aPreviousFrameBuffer, aOffset, mOGLManager);
}
#endif // MOZ_IPC

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

@ -60,12 +60,8 @@ static void ContainerRender(Container* aContainer,
int aPreviousFrameBuffer,
const nsIntPoint& aOffset,
LayerManagerOGL* aManager);
template<class Container>
static bool ShouldUseIntermediate(Container* aContainer,
float aOpacity,
const gfx3DMatrix& aMatrix);
class ContainerLayerOGL : public ContainerLayer,
class ContainerLayerOGL : public ContainerLayer,
public LayerOGL
{
template<class Container>
@ -79,10 +75,6 @@ class ContainerLayerOGL : public ContainerLayer,
int aPreviousFrameBuffer,
const nsIntPoint& aOffset,
LayerManagerOGL* aManager);
template<class Container>
friend bool ShouldUseIntermediate(Container* aContainer,
float aOpacity,
const gfx3DMatrix& aMatrix);
public:
ContainerLayerOGL(LayerManagerOGL *aManager);
@ -100,9 +92,12 @@ public:
LayerOGL* GetFirstChildOGL();
virtual void RenderLayer(int aPreviousFrameBuffer,
const nsIntPoint& aOffset,
float aOpacity,
const gfx3DMatrix& aMatrix);
const nsIntPoint& aOffset);
virtual void ComputeEffectiveTransforms(const gfx3DMatrix& aTransformToSurface)
{
DefaultComputeEffectiveTransforms(aTransformToSurface);
}
};
#ifdef MOZ_IPC
@ -120,10 +115,6 @@ class ShadowContainerLayerOGL : public ShadowContainerLayer,
int aPreviousFrameBuffer,
const nsIntPoint& aOffset,
LayerManagerOGL* aManager);
template<class Container>
friend bool ShouldUseIntermediate(Container* aContainer,
float aOpacity,
const gfx3DMatrix& aMatrix);
public:
ShadowContainerLayerOGL(LayerManagerOGL *aManager);
@ -141,9 +132,12 @@ public:
LayerOGL* GetFirstChildOGL();
virtual void RenderLayer(int aPreviousFrameBuffer,
const nsIntPoint& aOffset,
float aOpacity,
const gfx3DMatrix& aMatrix);
const nsIntPoint& aOffset);
virtual void ComputeEffectiveTransforms(const gfx3DMatrix& aTransformToSurface)
{
DefaultComputeEffectiveTransforms(aTransformToSurface);
}
};
#endif // MOZ_IPC

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

@ -371,9 +371,7 @@ ImageLayerOGL::GetLayer()
void
ImageLayerOGL::RenderLayer(int,
const nsIntPoint& aOffset,
float aOpacity,
const gfx3DMatrix& aMatrix)
const nsIntPoint& aOffset)
{
if (!GetContainer())
return;
@ -412,8 +410,8 @@ ImageLayerOGL::RenderLayer(int,
program->SetLayerQuadRect(nsIntRect(0, 0,
yuvImage->mSize.width,
yuvImage->mSize.height));
program->SetLayerTransform(GetEffectiveTransform() * aMatrix);
program->SetLayerOpacity(GetOpacity() * aOpacity);
program->SetLayerTransform(GetEffectiveTransform());
program->SetLayerOpacity(GetEffectiveOpacity());
program->SetRenderOffset(aOffset);
program->SetYCbCrTextureUnits(0, 1, 2);
@ -441,8 +439,8 @@ ImageLayerOGL::RenderLayer(int,
program->SetLayerQuadRect(nsIntRect(0, 0,
cairoImage->mSize.width,
cairoImage->mSize.height));
program->SetLayerTransform(GetEffectiveTransform() * aMatrix);
program->SetLayerOpacity(GetOpacity() * aOpacity);
program->SetLayerTransform(GetEffectiveTransform());
program->SetLayerOpacity(GetEffectiveOpacity());
program->SetRenderOffset(aOffset);
program->SetTextureUnit(0);
@ -789,9 +787,7 @@ ShadowImageLayerOGL::GetLayer()
void
ShadowImageLayerOGL::RenderLayer(int aPreviousFrameBuffer,
const nsIntPoint& aOffset,
float aOpacity,
const gfx3DMatrix& aMatrix)
const nsIntPoint& aOffset)
{
mOGLManager->MakeCurrent();
@ -805,8 +801,8 @@ ShadowImageLayerOGL::RenderLayer(int aPreviousFrameBuffer,
program->Activate();
program->SetLayerQuadRect(nsIntRect(nsIntPoint(0, 0), mTexImage->GetSize()));
program->SetLayerTransform(mTransform * aMatrix);
program->SetLayerOpacity(GetOpacity() * aOpacity);
program->SetLayerTransform(GetEffectiveTransform());
program->SetLayerOpacity(GetEffectiveOpacity());
program->SetRenderOffset(aOffset);
program->SetTextureUnit(0);

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

@ -184,9 +184,7 @@ public:
virtual Layer* GetLayer();
virtual void RenderLayer(int aPreviousFrameBuffer,
const nsIntPoint& aOffset,
float aOpacity,
const gfx3DMatrix& aMatrix);
const nsIntPoint& aOffset);
};
class THEBES_API PlanarYCbCrImageOGL : public PlanarYCbCrImage
@ -264,9 +262,7 @@ public:
virtual Layer* GetLayer();
virtual void RenderLayer(int aPreviousFrameBuffer,
const nsIntPoint& aOffset,
float aOpacity,
const gfx3DMatrix& aMatrix);
const nsIntPoint& aOffset);
private:
nsRefPtr<TextureImage> mTexImage;

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

@ -404,6 +404,10 @@ LayerManagerOGL::EndTransaction(DrawThebesLayerCallback aCallback,
return;
}
// The results of our drawing always go directly into a pixel buffer,
// so we don't need to pass any global transform here.
mRoot->ComputeEffectiveTransforms(gfx3DMatrix());
mThebesLayerCallback = aCallback;
mThebesLayerCallbackData = aCallbackData;
@ -591,7 +595,7 @@ LayerManagerOGL::Render()
// Render our layers.
RootLayer()->RenderLayer(mGLContext->IsDoubleBuffered() ? 0 : mBackBufferFBO,
nsIntPoint(0, 0), 1.0, gfx3DMatrix());
nsIntPoint(0, 0));
DEBUG_GL_ERROR_CHECK(mGLContext);

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

@ -462,9 +462,7 @@ public:
virtual Layer* GetLayer() = 0;
virtual void RenderLayer(int aPreviousFrameBuffer,
const nsIntPoint& aOffset,
float aOpacity,
const gfx3DMatrix& aMatrix) = 0;
const nsIntPoint& aOffset) = 0;
typedef mozilla::gl::GLContext GLContext;

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

@ -133,8 +133,7 @@ public:
virtual PaintState BeginPaint(ContentType aContentType) = 0;
void RenderTo(const nsIntPoint& aOffset, LayerManagerOGL* aManager,
float aOpacity, const gfx3DMatrix& aMatrix);
void RenderTo(const nsIntPoint& aOffset, LayerManagerOGL* aManager);
nsIntSize GetSize() {
if (mTexImage)
@ -154,9 +153,7 @@ protected:
void
ThebesLayerBufferOGL::RenderTo(const nsIntPoint& aOffset,
LayerManagerOGL* aManager,
float aOpacity,
const gfx3DMatrix& aMatrix)
LayerManagerOGL* aManager)
{
if (!mTexImage)
return;
@ -181,8 +178,8 @@ ThebesLayerBufferOGL::RenderTo(const nsIntPoint& aOffset,
nsIntRect quadRect = *iterRect;
program->Activate();
program->SetLayerQuadRect(quadRect);
program->SetLayerOpacity(mLayer->GetOpacity() * aOpacity);
program->SetLayerTransform(mLayer->GetEffectiveTransform() * aMatrix);
program->SetLayerOpacity(mLayer->GetEffectiveOpacity());
program->SetLayerTransform(mLayer->GetEffectiveTransform());
program->SetRenderOffset(aOffset);
program->SetTextureUnit(0);
DEBUG_GL_ERROR_CHECK(gl());
@ -512,9 +509,7 @@ ThebesLayerOGL::InvalidateRegion(const nsIntRegion &aRegion)
void
ThebesLayerOGL::RenderLayer(int aPreviousFrameBuffer,
const nsIntPoint& aOffset,
float aOpacity,
const gfx3DMatrix& aMatrix)
const nsIntPoint& aOffset)
{
if (!mBuffer && !CreateSurface()) {
return;
@ -544,7 +539,7 @@ ThebesLayerOGL::RenderLayer(int aPreviousFrameBuffer,
DEBUG_GL_ERROR_CHECK(gl());
gl()->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, aPreviousFrameBuffer);
mBuffer->RenderTo(aOffset, mOGLManager, aOpacity, aMatrix);
mBuffer->RenderTo(aOffset, mOGLManager);
DEBUG_GL_ERROR_CHECK(gl());
}
@ -704,9 +699,7 @@ ShadowThebesLayerOGL::IsEmpty()
void
ShadowThebesLayerOGL::RenderLayer(int aPreviousFrameBuffer,
const nsIntPoint& aOffset,
float aOpacity,
const gfx3DMatrix& aMatrix)
const nsIntPoint& aOffset)
{
if (!mBuffer) {
return;
@ -718,7 +711,7 @@ ShadowThebesLayerOGL::RenderLayer(int aPreviousFrameBuffer,
DEBUG_GL_ERROR_CHECK(gl());
gl()->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, aPreviousFrameBuffer);
mBuffer->RenderTo(aOffset, mOGLManager, aOpacity, aMatrix);
mBuffer->RenderTo(aOffset, mOGLManager);
DEBUG_GL_ERROR_CHECK(gl());
}

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

@ -76,9 +76,7 @@ public:
Layer* GetLayer();
virtual PRBool IsEmpty();
virtual void RenderLayer(int aPreviousFrameBuffer,
const nsIntPoint& aOffset,
float aOpacity,
const gfx3DMatrix& aMatrix);
const nsIntPoint& aOffset);
private:
friend class BasicBufferOGL;
@ -112,9 +110,7 @@ public:
Layer* GetLayer();
virtual PRBool IsEmpty();
virtual void RenderLayer(int aPreviousFrameBuffer,
const nsIntPoint& aOffset,
float aOpacity,
const gfx3DMatrix& aMatrix);
const nsIntPoint& aOffset);
private:
nsRefPtr<ShadowBufferOGL> mBuffer;

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

@ -3,7 +3,7 @@
<head>
<style>
#d { width:200px; border:10px solid rgba(200,200,200,0.99); }
#e { width:200px; height:200px; opacity:0.99; background-color:rgb(200,200,200); }
#e { width:196px; height:196px; opacity:0.99; background-color:rgb(200,200,200); padding:2px; }
#f { width:200px; height:10px; opacity:0.8; }
</style>
</head>

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

@ -3,7 +3,7 @@
<head>
<style>
#d { width:200px; }
#e { width:200px; height:200px; opacity:0.99; }
#e { width:196px; height:196px; opacity:0.99; border:2px solid rgb(200,200,200); }
#f { width:200px; height:10px; }
</style>
</head>

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

@ -0,0 +1,6 @@
<!DOCTYPE HTML>
<html>
<body>
<div style="position:absolute; top:10px; left:0; height:1px; width:200px; background:black"></div>
</body>
</html>

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

@ -0,0 +1,12 @@
<!DOCTYPE HTML>
<html>
<body>
<canvas id="c" width="200" height="20" style="position:absolute; top:10.4px; left:0"></canvas>
<script>
var c = document.getElementById("c");
var ctx = c.getContext("2d");
ctx.fillStyle = "black";
ctx.fillRect(0, 0, 200, 1);
</script>
</body>
</html>

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

@ -0,0 +1,7 @@
<!DOCTYPE HTML>
<html>
<body>
<div style="position:absolute; top:10px; left:0; width:200px; height:19px;
opacity:0.999; border:1px solid black; border-top:2px solid black; background-color:white"></div>
</body>
</html>

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

@ -0,0 +1,16 @@
<!DOCTYPE HTML>
<html>
<body>
<div style="opacity:0.999;">
<canvas id="c" width="200" height="20" style="position:absolute; top:10.4px; left:0; border:1px solid black"></canvas>
</div>
<div style="position:absolute; top:10px; left:0; width:200px; height:19px;
opacity:0.999; border:1px solid black; border-top:2px solid black; background-color:white"></div>
<script>
var c = document.getElementById("c");
var ctx = c.getContext("2d");
ctx.fillStyle = "black";
ctx.fillRect(0, 0, 200, 1);
</script>
</body>
</html>

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

@ -0,0 +1,6 @@
<!DOCTYPE HTML>
<html>
<body>
<div style="width:12px; height:12px; background:black; position:absolute; top:0px"></div>
</body>
</html>

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

@ -0,0 +1,15 @@
<!DOCTYPE HTML>
<html>
<body>
<div style="-moz-transform:translate(0.4px); position:absolute; top:0px;">
<canvas style="margin-left:0.4px; border:1px solid black; display:block" width="10" height="10" id="c"></canvas>
</div>
<div style="position:absolute; top:0px; width:12px; height:12px; background:black;"></div>
<script>
var c = document.getElementById("c");
var ctx = c.getContext('2d');
ctx.fillStyle = "black";
ctx.fillRect(0, 0, c.width, c.height);
</script>
</body>
</html>

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

@ -0,0 +1,10 @@
<!DOCTYPE HTML>
<html>
<body>
<div style="opacity:0.999; border-left:1px solid red; width:12px;">
<div style="position:relative; left:1px; opacity:0.999; border-left:1px solid rgb(0,255,0);">
<div style="width:10px; height:10px; background:black"></div>
</div>
</div>
</body>
</html>

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

@ -0,0 +1,15 @@
<!DOCTYPE HTML>
<html>
<body>
<div style="-moz-transform:translate(0.4px); opacity:0.999; border-left:1px solid red; width:12px;">
<div style="-moz-transform:translate(0.4px); opacity:0.999; border-left:1px solid rgb(0,255,0);">
<canvas width="10" height="10" id="c" style="display:block"></canvas>
</div>
</div>
<script>
var ctx = document.getElementById("c").getContext("2d");
ctx.fillStyle = "black";
ctx.fillRect(0, 0, 10, 10);
</script>
</body>
</html>

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

@ -1525,8 +1525,12 @@ fails-if(!haveTestPlugin) == 599476.html 599476-ref.html
== 600045-1.html 600045-1-ref.html
== 600803-1.html 600803-1-ref.html
== 600974-1.html 600974-1-ref.html
== 604737.html 604737-ref.html
== 600974-2.html 600974-1-ref.html
== 600974-3.html 600974-1-ref.html
== 602200-1.html 602200-1-ref.html
== 602200-2.html 602200-2-ref.html
== 602200-3.html 602200-3-ref.html
== 602200-4.html 602200-4-ref.html
== 604737.html 604737-ref.html
== 605138-1.html 605138-1-ref.html
== 605157-1.xhtml 605157-1-ref.xhtml

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

@ -6,6 +6,7 @@
position:absolute;
left:0px; top:0px;
width:400px; height:400px;
border:2px solid blue;
background-color: rgb(160,160,160);
opacity:0.5;
z-index:1;

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

@ -5,7 +5,8 @@
#one {
position:absolute;
left:0px; top:0px;
width:400px; height:400px;
width:404px; height:404px;
border:2px solid blue;
opacity:.5;
z-index:1;
}