зеркало из https://github.com/mozilla/pjs.git
Bug 607936 - Make possible to apply transform on topLevel LayerManager scene r=matt,roc a=joe
--HG-- extra : rebase_source : 7983ed59e06d33e5c17878a24434eef409684d25
This commit is contained in:
Родитель
1128a62a40
Коммит
db3832bc1b
|
@ -211,7 +211,8 @@ ContainerRender(Container* aContainer,
|
|||
childOffset.y = visibleRect.y;
|
||||
|
||||
aContainer->gl()->PushViewportRect();
|
||||
aManager->SetupPipeline(visibleRect.width, visibleRect.height);
|
||||
aManager->SetupPipeline(visibleRect.width, visibleRect.height,
|
||||
LayerManagerOGL::DontApplyWorldTransform);
|
||||
|
||||
} else {
|
||||
frameBuffer = aPreviousFrameBuffer;
|
||||
|
@ -256,6 +257,11 @@ ContainerRender(Container* aContainer,
|
|||
if (needsFramebuffer) {
|
||||
scissorRect.MoveBy(- visibleRect.TopLeft());
|
||||
} else {
|
||||
if (!frameBuffer) {
|
||||
// Transform scissorRect here
|
||||
aManager->WorldTransformRect(scissorRect);
|
||||
}
|
||||
|
||||
if (!aPreviousFrameBuffer) {
|
||||
/**
|
||||
* glScissor coordinates are oriented with 0,0 being at the bottom left,
|
||||
|
@ -298,7 +304,8 @@ ContainerRender(Container* aContainer,
|
|||
// Restore the viewport
|
||||
aContainer->gl()->PopViewportRect();
|
||||
nsIntRect viewport = aContainer->gl()->ViewportRect();
|
||||
aManager->SetupPipeline(viewport.width, viewport.height);
|
||||
aManager->SetupPipeline(viewport.width, viewport.height,
|
||||
LayerManagerOGL::ApplyWorldTransform);
|
||||
|
||||
aContainer->gl()->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, aPreviousFrameBuffer);
|
||||
aContainer->gl()->fDeleteFramebuffers(1, &frameBuffer);
|
||||
|
|
|
@ -550,6 +550,7 @@ LayerManagerOGL::Render()
|
|||
|
||||
nsIntRect rect;
|
||||
mWidget->GetClientBounds(rect);
|
||||
WorldTransformRect(rect);
|
||||
|
||||
GLint width = rect.width;
|
||||
GLint height = rect.height;
|
||||
|
@ -575,7 +576,7 @@ LayerManagerOGL::Render()
|
|||
DEBUG_GL_ERROR_CHECK(mGLContext);
|
||||
|
||||
SetupBackBuffer(width, height);
|
||||
SetupPipeline(width, height);
|
||||
SetupPipeline(width, height, ApplyWorldTransform);
|
||||
|
||||
// Default blend function implements "OVER"
|
||||
mGLContext->fBlendFuncSeparate(LOCAL_GL_ONE, LOCAL_GL_ONE_MINUS_SRC_ALPHA,
|
||||
|
@ -588,6 +589,7 @@ LayerManagerOGL::Render()
|
|||
|
||||
if (clipRect) {
|
||||
nsIntRect r = *clipRect;
|
||||
WorldTransformRect(r);
|
||||
if (!mGLContext->IsDoubleBuffered() && !mTarget)
|
||||
mGLContext->FixWindowCoordinateRect(r, mWidgetSize.height);
|
||||
mGLContext->fScissor(r.x, r.y, r.width, r.height);
|
||||
|
@ -662,6 +664,8 @@ LayerManagerOGL::Render()
|
|||
nsIntRegionRectIterator iter(mClippingRegion);
|
||||
|
||||
while ((r = iter.Next()) != nsnull) {
|
||||
nsIntRect cRect = *r; r = &cRect;
|
||||
WorldTransformRect(cRect);
|
||||
float left = (GLfloat)r->x / width;
|
||||
float right = (GLfloat)r->XMost() / width;
|
||||
float top = (GLfloat)r->y / height;
|
||||
|
@ -706,7 +710,32 @@ LayerManagerOGL::Render()
|
|||
}
|
||||
|
||||
void
|
||||
LayerManagerOGL::SetupPipeline(int aWidth, int aHeight)
|
||||
LayerManagerOGL::SetWorldTransform(const gfxMatrix& aMatrix)
|
||||
{
|
||||
NS_ASSERTION(aMatrix.PreservesAxisAlignedRectangles(),
|
||||
"SetWorldTransform only accepts matrices that satisfy PreservesAxisAlignedRectangles");
|
||||
NS_ASSERTION(!aMatrix.HasNonIntegerScale(),
|
||||
"SetWorldTransform only accepts matrices with integer scale");
|
||||
|
||||
mWorldMatrix = aMatrix;
|
||||
}
|
||||
|
||||
gfxMatrix&
|
||||
LayerManagerOGL::GetWorldTransform(void)
|
||||
{
|
||||
return mWorldMatrix;
|
||||
}
|
||||
|
||||
void
|
||||
LayerManagerOGL::WorldTransformRect(nsIntRect& aRect)
|
||||
{
|
||||
gfxRect grect(aRect.x, aRect.y, aRect.width, aRect.height);
|
||||
grect = mWorldMatrix.TransformBounds(grect);
|
||||
aRect.SetRect(grect.pos.x, grect.pos.y, grect.size.width, grect.size.height);
|
||||
}
|
||||
|
||||
void
|
||||
LayerManagerOGL::SetupPipeline(int aWidth, int aHeight, WorldTransforPolicy aTransformPolicy)
|
||||
{
|
||||
// Set the viewport correctly.
|
||||
//
|
||||
|
@ -744,6 +773,10 @@ LayerManagerOGL::SetupPipeline(int aWidth, int aHeight)
|
|||
viewMatrix._42 = -1.0f;
|
||||
}
|
||||
|
||||
if (aTransformPolicy == ApplyWorldTransform) {
|
||||
viewMatrix = gfx3DMatrix::From2D(mWorldMatrix) * viewMatrix;
|
||||
}
|
||||
|
||||
SetLayerProgramProjectionMatrix(viewMatrix);
|
||||
}
|
||||
|
||||
|
|
|
@ -372,11 +372,25 @@ public:
|
|||
return mWidgetSize;
|
||||
}
|
||||
|
||||
enum WorldTransforPolicy {
|
||||
ApplyWorldTransform,
|
||||
DontApplyWorldTransform
|
||||
};
|
||||
|
||||
/**
|
||||
* Setup the viewport and projection matrix for rendering
|
||||
* to a window of the given dimensions.
|
||||
*/
|
||||
void SetupPipeline(int aWidth, int aHeight);
|
||||
void SetupPipeline(int aWidth, int aHeight, WorldTransforPolicy aTransformPolicy);
|
||||
|
||||
/**
|
||||
* Setup World transform matrix.
|
||||
* Transform will be ignored if it is not PreservesAxisAlignedRectangles
|
||||
* or has non integer scale
|
||||
*/
|
||||
void SetWorldTransform(const gfxMatrix& aMatrix);
|
||||
gfxMatrix& GetWorldTransform(void);
|
||||
void WorldTransformRect(nsIntRect& aRect);
|
||||
|
||||
private:
|
||||
/** Widget associated with this layer manager */
|
||||
|
@ -455,6 +469,7 @@ private:
|
|||
* while rendering */
|
||||
DrawThebesLayerCallback mThebesLayerCallback;
|
||||
void *mThebesLayerCallbackData;
|
||||
gfxMatrix mWorldMatrix;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -281,6 +281,14 @@ public:
|
|||
|| (FuzzyEqual(xy, 0.0) && FuzzyEqual(yx, 0.0)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the matrix has non-integer scale
|
||||
*/
|
||||
PRBool HasNonIntegerScale() const {
|
||||
return !FuzzyEqual(xx, NS_floor(xx + 0.5)) ||
|
||||
!FuzzyEqual(yy, NS_floor(yy + 0.5));
|
||||
}
|
||||
|
||||
private:
|
||||
static PRBool FuzzyEqual(gfxFloat aV1, gfxFloat aV2) {
|
||||
return fabs(aV2 - aV1) < 1e-6;
|
||||
|
|
Загрузка…
Ссылка в новой задаче