Bug 717283 - Use tiles on-demand. r=pcwalton, snorp

Instead of tying the tile-buffer in MultiTileLayer directly to the back-buffer
of the page, make sure rendering is always aligned to the tile grid and use
tiles on-demand. This makes better use of tiles when panning/zooming, and opens
up the route for further optimisations.
This commit is contained in:
Chris Lord
2012-01-20 17:36:56 +00:00
parent a535148456
commit 662a91daa2
11 changed files with 595 additions and 270 deletions

View File

@@ -1195,13 +1195,22 @@ nsWindow::OnDraw(AndroidGeckoEvent *ae)
return;
}
nsAutoString metadata;
if (metadataProvider) {
metadataProvider->GetDrawMetadata(metadata);
}
AndroidGeckoSoftwareLayerClient &client =
AndroidBridge::Bridge()->GetSoftwareLayerClient();
client.BeginDrawing(gAndroidBounds.width, gAndroidBounds.height);
if (!client.BeginDrawing(gAndroidBounds.width, gAndroidBounds.height, metadata, HasDirectTexture())) {
return;
}
nsIntPoint renderOffset;
client.GetRenderOffset(renderOffset);
nsIntRect dirtyRect = ae->Rect().Intersect(nsIntRect(0, 0, gAndroidBounds.width, gAndroidBounds.height));
nsAutoString metadata;
unsigned char *bits = NULL;
if (HasDirectTexture()) {
if (sDirectTexture->Width() != gAndroidBounds.width ||
@@ -1220,37 +1229,32 @@ nsWindow::OnDraw(AndroidGeckoEvent *ae)
int tileWidth = (gAndroidTileSize.width > 0) ? gAndroidTileSize.width : gAndroidBounds.width;
int tileHeight = (gAndroidTileSize.height > 0) ? gAndroidTileSize.height : gAndroidBounds.height;
bool drawSuccess = true;
int offset = 0;
for (int y = 0; y < gAndroidBounds.height; y += tileHeight) {
for (int x = 0; x < gAndroidBounds.width; x += tileWidth) {
int width = NS_MIN(tileWidth, gAndroidBounds.width - x);
int height = NS_MIN(tileHeight, gAndroidBounds.height - y);
// It is assumed that the buffer has been over-allocated so that not
// only is the tile-size constant, but that a render-offset of anything
// up to (but not including) the tile size could be accommodated.
for (int y = 0; y < gAndroidBounds.height + gAndroidTileSize.height; y += tileHeight) {
for (int x = 0; x < gAndroidBounds.width + gAndroidTileSize.width; x += tileWidth) {
nsRefPtr<gfxImageSurface> targetSurface =
new gfxImageSurface(bits + offset,
gfxIntSize(width, height),
width * 2,
gfxIntSize(tileWidth, tileHeight),
tileWidth * 2,
gfxASurface::ImageFormatRGB16_565);
offset += width * height * 2;
offset += tileWidth * tileHeight * 2;
if (targetSurface->CairoStatus()) {
ALOG("### Failed to create a valid surface from the bitmap");
drawSuccess = false;
break;
} else {
targetSurface->SetDeviceOffset(gfxPoint(-x, -y));
targetSurface->SetDeviceOffset(gfxPoint(renderOffset.x - x,
renderOffset.y - y));
DrawTo(targetSurface, dirtyRect);
}
}
}
// Don't fill in the draw metadata on an unsuccessful draw
if (drawSuccess && metadataProvider) {
metadataProvider->GetDrawMetadata(metadata);
}
}
if (HasDirectTexture()) {
@@ -1259,7 +1263,7 @@ nsWindow::OnDraw(AndroidGeckoEvent *ae)
client.UnlockBuffer();
}
client.EndDrawing(dirtyRect, metadata, HasDirectTexture());
client.EndDrawing(dirtyRect);
return;
#endif