Bug 709120 - Add tiled buffer support for Android/native. r=pcwalton

This adds support for rendering to a tiled software buffer when using the
Java compositor. Tiles are assumed to be packed tight and stored sequentially,
by row.
This commit is contained in:
Chris Lord 2012-01-06 11:22:11 +00:00
Родитель 6210dfb376
Коммит 7fc2650acb
3 изменённых файлов: 55 добавлений и 24 удалений

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

@ -408,6 +408,10 @@ AndroidGeckoEvent::Init(JNIEnv *jenv, jobject jobj)
mType = jenv->GetIntField(jobj, jTypeField);
switch (mType) {
case TILE_SIZE:
ReadP0Field(jenv);
break;
case SIZE_CHANGED:
ReadP0Field(jenv);
ReadP1Field(jenv);

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

@ -532,6 +532,7 @@ public:
ACTIVITY_START = 17,
BROADCAST = 19,
VIEWPORT = 20,
TILE_SIZE = 21,
dummy_java_enum_list_end
};

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

@ -87,6 +87,7 @@ NS_IMPL_ISUPPORTS_INHERITED0(nsWindow, nsBaseWidget)
// The dimensions of the current android view
static gfxIntSize gAndroidBounds = gfxIntSize(0, 0);
static gfxIntSize gAndroidTileSize = gfxIntSize(0, 0);
static gfxIntSize gAndroidScreenBounds;
#ifdef ACCESSIBILITY
@ -981,6 +982,12 @@ nsWindow::OnGlobalAndroidEvent(AndroidGeckoEvent *ae)
win->OnDraw(ae);
break;
case AndroidGeckoEvent::TILE_SIZE: {
gAndroidTileSize.width = ae->P0().x;
gAndroidTileSize.height = ae->P0().y;
break;
}
case AndroidGeckoEvent::IME_EVENT:
win->UserActivity();
if (win->mFocus) {
@ -1202,36 +1209,55 @@ nsWindow::OnDraw(AndroidGeckoEvent *ae)
}
if (!bits) {
ALOG("### Failed to lock buffer");
if (sHasDirectTexture) {
sDirectTexture->Unlock();
} else {
client.UnlockBuffer();
}
} else {
nsRefPtr<gfxImageSurface> targetSurface =
new gfxImageSurface(bits, gfxIntSize(gAndroidBounds.width, gAndroidBounds.height), gAndroidBounds.width * 2,
gfxASurface::ImageFormatRGB16_565);
if (targetSurface->CairoStatus()) {
ALOG("### Failed to create a valid surface from the bitmap");
} else {
if (sHasDirectTexture) {
// XXX: lock only the dirty rect above and pass it in here
DrawTo(targetSurface);
} else {
DrawTo(targetSurface, ae->Rect());
}
// If tile size is 0,0, we assume we only have a single tile
int tileWidth = (gAndroidTileSize.width > 0) ? gAndroidTileSize.width : gAndroidBounds.width;
int tileHeight = (gAndroidTileSize.height > 0) ? gAndroidTileSize.height : gAndroidBounds.height;
if (metadataProvider) {
metadataProvider->GetDrawMetadata(metadata);
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);
nsRefPtr<gfxImageSurface> targetSurface =
new gfxImageSurface(bits + offset,
gfxIntSize(width, height),
width * 2,
gfxASurface::ImageFormatRGB16_565);
offset += width * height * 2;
if (targetSurface->CairoStatus()) {
ALOG("### Failed to create a valid surface from the bitmap");
drawSuccess = false;
break;
} else {
if (sHasDirectTexture) {
// XXX: lock only the dirty rect above and pass it in here
DrawTo(targetSurface);
} else {
targetSurface->SetDeviceOffset(gfxPoint(-x, -y));
DrawTo(targetSurface, ae->Rect());
}
}
}
}
if (sHasDirectTexture) {
sDirectTexture->Unlock();
} else {
client.UnlockBuffer();
// Don't fill in the draw metadata on an unsuccessful draw
if (drawSuccess && metadataProvider) {
metadataProvider->GetDrawMetadata(metadata);
}
}
if (sHasDirectTexture) {
sDirectTexture->Unlock();
} else {
client.UnlockBuffer();
}
client.EndDrawing(ae->Rect(), metadata);
return;
#endif