Implement logic needed for simple async scrolling.

This commit is contained in:
Ali Juma 2012-02-01 14:31:34 -05:00
parent 106b0e77a3
commit 03df2cf07f
2 changed files with 189 additions and 0 deletions

View File

@ -79,11 +79,31 @@ CompositorParent::RecvStop()
return true;
}
void
CompositorParent::ScheduleComposition()
{
CancelableTask *composeTask = NewRunnableMethod(this, &CompositorParent::Composite);
MessageLoop::current()->PostTask(FROM_HERE, composeTask);
// Test code for async scrolling.
#ifdef OMTC_TEST_ASYNC_SCROLLING
static bool scrollScheduled = false;
if (!scrollScheduled) {
CancelableTask *composeTask2 = NewRunnableMethod(this,
&CompositorParent::TestScroll);
MessageLoop::current()->PostDelayedTask(FROM_HERE, composeTask2, 500);
scrollScheduled = true;
}
#endif
}
void
CompositorParent::SetTransformation(float aScale, nsIntPoint aScrollOffset)
{
mXScale = aScale;
mYScale = aScale;
mScrollOffset = aScrollOffset;
}
void
@ -113,6 +133,113 @@ SetShadowProperties(Layer* aLayer)
}
}
static double GetXScale(const gfx3DMatrix& aTransform)
{
return aTransform._11;
}
static double GetYScale(const gfx3DMatrix& aTransform)
{
return aTransform._22;
}
static void ReverseTranslate(gfx3DMatrix& aTransform, ViewTransform& aViewTransform)
{
aTransform._41 -= aViewTransform.mTranslation.x / aViewTransform.mXScale;
aTransform._42 -= aViewTransform.mTranslation.y / aViewTransform.mYScale;
}
void
CompositorParent::TransformShadowTree(Layer* aLayer, const ViewTransform& aTransform,
float aTempScaleDiffX, float aTempScaleDiffY)
{
ShadowLayer* shadow = aLayer->AsShadowLayer();
gfx3DMatrix shadowTransform = aLayer->GetTransform();
ViewTransform layerTransform = aTransform;
ContainerLayer* container = aLayer->AsContainerLayer();
if (container && container->GetFrameMetrics().IsScrollable()) {
const FrameMetrics* metrics = &container->GetFrameMetrics();
const gfx3DMatrix& currentTransform = aLayer->GetTransform();
aTempScaleDiffX *= GetXScale(shadowTransform);
aTempScaleDiffY *= GetYScale(shadowTransform);
nsIntPoint metricsScrollOffset = metrics->mViewportScrollOffset;
nsIntPoint scrollCompensation(
(mScrollOffset.x / aTempScaleDiffX - metricsScrollOffset.x) * mXScale,
(mScrollOffset.y / aTempScaleDiffY - metricsScrollOffset.y) * mYScale);
ViewTransform treeTransform(-scrollCompensation, mXScale,
mYScale);
shadowTransform = gfx3DMatrix(treeTransform) * currentTransform;
layerTransform = treeTransform;
}
// Uncomment to deal with position:fixed.
/*
if (aLayer->GetIsFixedPosition() &&
!aLayer->GetParent()->GetIsFixedPosition()) {
printf_stderr("Correcting for position fixed\n");
ReverseTranslate(shadowTransform, layerTransform);
const nsIntRect* clipRect = shadow->GetShadowClipRect();
if (clipRect) {
nsIntRect transformedClipRect(*clipRect);
transformedClipRect.MoveBy(shadowTransform._41, shadowTransform._42);
shadow->SetShadowClipRect(&transformedClipRect);
}
}*/
shadow->SetShadowTransform(shadowTransform);
// Uncomment the following when we want to deal with position:fixed.
// Note that we need to modify other code to ensure that position:fixed
// things get their own layer. See Bug 607417.
/*
for (Layer* child = aLayer->GetFirstChild(); child;
child = child->GetNextSibling()) {
TransformShadowTree(child, layerTransform, aTempScaleDiffX,
aTempScaleDiffY);
}*/
}
void
CompositorParent::AsyncRender()
{
if (mStopped || !mLayerManager) {
return;
}
Layer* root = mLayerManager->GetRoot();
ContainerLayer* container = root->AsContainerLayer();
if (!container)
return;
FrameMetrics metrics = container->GetFrameMetrics();
/*
printf("FrameMetrics: mViewPort: X: %d, Y: %d, Width: %d, Height: %d ",
metrics.mViewport.X(), metrics.mViewport.Y(), metrics.mViewport.Width(),
metrics.mViewport.Height());
printf("mDisplayPort: X: %d, Y: %d, Width: %d, Height: %d ",
metrics.mDisplayPort.X(), metrics.mDisplayPort.Y(), metrics.mDisplayPort.Width(),
metrics.mDisplayPort.Height());
printf("mContentSize: width: %d, height: %d ", metrics.mContentSize.width,
metrics. mContentSize.height);
printf("mViewPortScrollOffset: x: %d, y: %d\n",
metrics.mViewportScrollOffset.x,
metrics.mViewportScrollOffset.y);
*/
// Modify framemetrics here, just as a test.
metrics.mScrollId = FrameMetrics::ROOT_SCROLL_ID;
container->SetFrameMetrics(metrics);
ViewTransform transform;
TransformShadowTree(root, transform);
Composite();
}
void
CompositorParent::ShadowLayersUpdated()
{
@ -127,6 +254,36 @@ CompositorParent::ShadowLayersUpdated()
ScheduleComposition();
}
// Test code for async scrolling.
#ifdef OMTC_TEST_ASYNC_SCROLLING
void
CompositorParent::TestScroll()
{
static int scrollFactor = 0;
static bool fakeScrollDownwards = true;
if (fakeScrollDownwards) {
scrollFactor++;
if (scrollFactor > 10) {
scrollFactor = 10;
fakeScrollDownwards = false;
}
} else {
scrollFactor--;
if (scrollFactor < 0) {
scrollFactor = 0;
fakeScrollDownwards = true;
}
}
SetTransformation(1.0+2.0*scrollFactor/10, nsIntPoint(-25*scrollFactor,
-25*scrollFactor));
printf_stderr("AsyncRender scroll factor:%d\n", scrollFactor);
AsyncRender();
CancelableTask *composeTask = NewRunnableMethod(this, &CompositorParent::TestScroll);
MessageLoop::current()->PostDelayedTask(FROM_HERE, composeTask, 1000/65);
}
#endif
PLayersParent*
CompositorParent::AllocPLayers(const LayersBackend &backendType)
{

View File

@ -52,6 +52,26 @@ namespace layers {
class LayerManager;
// Represents (affine) transforms that are calculated from a content view.
struct ViewTransform {
ViewTransform(nsIntPoint aTranslation = nsIntPoint(0, 0), float aXScale = 1, float aYScale = 1)
: mTranslation(aTranslation)
, mXScale(aXScale)
, mYScale(aYScale)
{}
operator gfx3DMatrix() const
{
return
gfx3DMatrix::ScalingMatrix(mXScale, mYScale, 1) *
gfx3DMatrix::Translation(mTranslation.x, mTranslation.y, 0);
}
nsIntPoint mTranslation;
float mXScale;
float mYScale;
};
class CompositorParent : public PCompositorParent,
public ShadowLayersManager
{
@ -67,6 +87,9 @@ public:
LayerManager* GetLayerManager() { return mLayerManager; }
void SetTransformation(float aScale, nsIntPoint aScrollOffset);
void AsyncRender();
protected:
virtual PLayersParent* AllocPLayers(const LayersBackend &backendType);
virtual bool DeallocPLayers(PLayersParent* aLayers);
@ -74,6 +97,12 @@ protected:
private:
void ScheduleComposition();
void Composite();
#ifdef OMTC_TEST_ASYNC_SCROLLING
void TestScroll();
#endif
void TransformShadowTree(Layer* aLayer, const ViewTransform& aTransform,
float aTempScaleDiffX = 1.0,
float aTempScaleDiffY = 1.0);
// Platform specific functions
#ifdef MOZ_WIDGET_ANDROID
@ -88,6 +117,9 @@ private:
nsRefPtr<LayerManager> mLayerManager;
bool mStopped;
nsIWidget* mWidget;
float mXScale;
float mYScale;
nsIntPoint mScrollOffset;
DISALLOW_EVIL_CONSTRUCTORS(CompositorParent);
};