Bug 743612: Fix OMTC on gonk. r=cjones

This commit is contained in:
Cody Brocious 2012-06-26 16:38:50 +02:00
parent 845b493515
commit eb4e80e2b5
3 changed files with 54 additions and 42 deletions

View File

@ -39,6 +39,7 @@ static struct fb_var_screeninfo sVi;
static size_t sActiveBuffer;
typedef vector<nsRefPtr<gfxImageSurface> > BufferVector;
BufferVector* sBuffers;
static gfxIntSize *sScreenSize = nsnull;
BufferVector& Buffers() { return *sBuffers; }
@ -57,7 +58,7 @@ SetGraphicsMode()
}
bool
Open(nsIntSize* aScreenSize)
Open()
{
if (0 <= sFd)
return true;
@ -98,28 +99,32 @@ Open(nsIntSize* aScreenSize)
// hard-coded numbers here.
gfxASurface::gfxImageFormat format = gfxASurface::ImageFormatRGB16_565;
int bytesPerPixel = gfxASurface::BytePerPixelFromFormat(format);
gfxIntSize size(sVi.xres, sVi.yres);
long stride = size.width * bytesPerPixel;
size_t numFrameBytes = stride * size.height;
if (!sScreenSize) {
sScreenSize = new gfxIntSize(sVi.xres, sVi.yres);
}
long stride = sScreenSize->width * bytesPerPixel;
size_t numFrameBytes = stride * sScreenSize->height;
sBuffers = new BufferVector(2);
unsigned char* data = static_cast<unsigned char*>(mem);
for (size_t i = 0; i < 2; ++i, data += numFrameBytes) {
memset(data, 0, numFrameBytes);
Buffers()[i] = new gfxImageSurface(data, size, stride, format);
Buffers()[i] = new gfxImageSurface(data, *sScreenSize, stride, format);
}
// Clear the framebuffer to a known state.
Present(nsIntRect());
*aScreenSize = size;
return true;
}
bool
GetSize(nsIntSize *aScreenSize) {
if (0 <= sFd)
// If the framebuffer has been opened, we should always have the size.
if (0 <= sFd || sScreenSize) {
*aScreenSize = *sScreenSize;
return true;
}
ScopedClose fd(open("/dev/graphics/fb0", O_RDWR));
if (0 > fd.get()) {
@ -132,7 +137,8 @@ GetSize(nsIntSize *aScreenSize) {
return false;
}
*aScreenSize = gfxIntSize(sVi.xres, sVi.yres);
sScreenSize = new gfxIntSize(sVi.xres, sVi.yres);
*aScreenSize = *sScreenSize;
return true;
}
@ -145,6 +151,8 @@ Close()
munmap(Buffers()[0]->Data(), sMappedSize);
delete sBuffers;
sBuffers = NULL;
delete sScreenSize;
sScreenSize = NULL;
close(sFd);
sFd = -1;

View File

@ -26,16 +26,17 @@ namespace Framebuffer {
// Present();
//
// Return true if the fbdev was successfully opened, along with the
// dimensions of the screen. If this fails, the result of all further
// calls is undefined. Open() is idempotent.
bool Open(nsIntSize* aScreenSize);
// Return true if the fbdev was successfully opened. If this fails,
// the result of all further calls is undefined. Open() is idempotent.
bool Open();
// After Close(), the result of all further calls is undefined.
// Close() is idempotent, and Open() can be called again after
// Close().
void Close();
// Return true if the fbdev was successfully opened or the size was
// already cached.
bool GetSize(nsIntSize *aScreenSize);
// Return the buffer to be drawn into, that will be the next frame.

View File

@ -49,6 +49,7 @@ static nsWindow *gFocusedWindow = nsnull;
static android::FramebufferNativeWindow *gNativeWindow = nsnull;
static bool sFramebufferOpen;
static bool sUsingOMTC;
static bool sScreenInitialized;
static nsRefPtr<gfxASurface> sOMTCSurface;
static pthread_t sFramebufferWatchThread;
@ -120,7 +121,7 @@ static void *frameBufferWatcher(void *) {
nsWindow::nsWindow()
{
if (!sGLContext && !sFramebufferOpen && !sUsingOMTC) {
if (!sScreenInitialized) {
// workaround Bug 725143
hal::SetScreenEnabled(true);
@ -132,34 +133,19 @@ nsWindow::nsWindow()
sUsingOMTC = UseOffMainThreadCompositing();
if (sUsingOMTC) {
sOMTCSurface = new gfxImageSurface(gfxIntSize(1, 1),
gfxASurface::ImageFormatRGB24);
}
// We (apparently) don't have a way to tell if allocating the
// fbs succeeded or failed.
gNativeWindow = new android::FramebufferNativeWindow();
if (sUsingOMTC) {
nsIntSize screenSize;
bool gotFB = Framebuffer::GetSize(&screenSize);
MOZ_ASSERT(gotFB);
gScreenBounds = nsIntRect(nsIntPoint(0, 0), screenSize);
sOMTCSurface = new gfxImageSurface(gfxIntSize(1, 1),
gfxASurface::ImageFormatRGB24);
} else {
sGLContext = GLContextProvider::CreateForWindow(this);
// CreateForWindow sets up gScreenBounds
if (!sGLContext) {
LOG("Failed to create GL context for fb, trying /dev/graphics/fb0");
// We can't delete gNativeWindow.
nsIntSize screenSize;
sFramebufferOpen = Framebuffer::Open(&screenSize);
gScreenBounds = nsIntRect(nsIntPoint(0, 0), screenSize);
if (!sFramebufferOpen) {
LOG("Failed to mmap fb(?!?), aborting ...");
NS_RUNTIMEABORT("Can't open GL context and can't fall back on /dev/graphics/fb0 ...");
}
}
}
nsIntSize screenSize;
bool gotFB = Framebuffer::GetSize(&screenSize);
MOZ_ASSERT(gotFB);
gScreenBounds = nsIntRect(nsIntPoint(0, 0), screenSize);
char propValue[PROPERTY_VALUE_MAX];
property_get("ro.sf.hwrotation", propValue, "0");
@ -181,6 +167,8 @@ nsWindow::nsWindow()
}
sVirtualBounds = gScreenBounds;
sScreenInitialized = true;
nsAppShell::NotifyScreenInitialized();
}
}
@ -492,6 +480,17 @@ nsWindow::GetLayerManager(PLayersChild* aShadowManager,
if (mLayerManager)
return mLayerManager;
// Set mUseAcceleratedRendering here to make it consistent with
// nsBaseWidget::GetLayerManager
mUseAcceleratedRendering = GetShouldAccelerate();
if (!mUseAcceleratedRendering) {
sFramebufferOpen = Framebuffer::Open();
if (!sFramebufferOpen) {
LOG("Failed to mmap fb(?!?), aborting ...");
NS_RUNTIMEABORT("Can't open GL context and can't fall back on /dev/graphics/fb0 ...");
}
}
nsWindow *topWindow = sTopWindows[0];
if (!topWindow) {
@ -505,18 +504,22 @@ nsWindow::GetLayerManager(PLayersChild* aShadowManager,
return mLayerManager;
}
DebugOnly<nsIntRect> fbBounds = gScreenBounds;
sGLContext = GLContextProvider::CreateForWindow(this);
MOZ_ASSERT(fbBounds == gScreenBounds);
if (sGLContext) {
nsRefPtr<LayerManagerOGL> layerManager = new LayerManagerOGL(this);
if (layerManager->Initialize(sGLContext))
if (layerManager->Initialize(sGLContext)) {
mLayerManager = layerManager;
else
return mLayerManager;
} else {
LOG("Could not create OGL LayerManager");
} else {
MOZ_ASSERT(sFramebufferOpen);
mLayerManager = new BasicShadowLayerManager(this);
}
}
mLayerManager = new BasicShadowLayerManager(this);
return mLayerManager;
}