Bug 950203 - Let GfxInfo on Android create its own GL context to get GL strings, instead of waiting on the compositor's - r=jrmuizel

This commit is contained in:
Benoit Jacob 2013-12-18 15:49:13 -05:00
parent 993600d299
commit 40cfd97476
4 changed files with 26 additions and 78 deletions

View File

@ -48,10 +48,6 @@
#endif
#include "GeckoProfiler.h"
#ifdef MOZ_WIDGET_ANDROID
#include "GfxInfo.h"
#endif
#define BUFFER_OFFSET(i) ((char *)nullptr + (i))
namespace mozilla {
@ -393,10 +389,6 @@ CompositorOGL::Initialize()
#ifdef MOZ_WIDGET_ANDROID
if (!mGLContext)
NS_RUNTIMEABORT("We need a context on Android");
// on Android, the compositor's GLContext is used to get GL strings for GfxInfo
nsCOMPtr<nsIGfxInfo> gfxInfo = do_GetService("@mozilla.org/gfx/info;1");
static_cast<widget::GfxInfo*>(gfxInfo.get())->InitializeGLStrings(mGLContext);
#endif
if (!mGLContext)

View File

@ -5,12 +5,12 @@
#include "GfxInfo.h"
#include "GLContext.h"
#include "GLContextProvider.h"
#include "nsUnicharUtils.h"
#include "prenv.h"
#include "prprf.h"
#include "nsHashKeys.h"
#include "nsVersionComparator.h"
#include "mozilla/Monitor.h"
#include "AndroidBridge.h"
#include "nsIWindowWatcher.h"
#include "nsServiceManagerUtils.h"
@ -24,36 +24,16 @@
namespace mozilla {
namespace widget {
static bool ExpectGLStringsToEverGetInitialized()
{
// In XPCShell, we don't have a compositor, so our GL strings will never get
// properly initialized.
// We need to know about that in GLStrings::EnsureInitialized to avoid waiting forever.
// The way we detect that we won't ever have a compositor, is that the nsWindowWatcher
// doesn't have a WindowCreator i.e. we won't create any windows. That is actually
// the root difference between xpcshell and real browsers, that causes the former
// not to create a window and a compositor.
nsCOMPtr<nsIWindowWatcher> wwatch(do_GetService(NS_WINDOWWATCHER_CONTRACTID));
if (!wwatch) {
return false;
}
bool hasWindowCreator = false;
nsresult rv = wwatch->HasWindowCreator(&hasWindowCreator);
return NS_SUCCEEDED(rv) && hasWindowCreator;
}
class GfxInfo::GLStrings
{
nsCString mVendor;
nsCString mRenderer;
nsCString mVersion;
bool mReady;
Monitor mMonitor;
public:
GLStrings()
: mReady(false)
, mMonitor("GfxInfo::mGLStringsMonitor")
{}
const nsCString& Vendor() {
@ -88,45 +68,31 @@ public:
void EnsureInitialized() {
if (!mReady) {
MonitorAutoLock autoLock(mMonitor);
// re-check mReady, as it could have changed before we locked.
if (!mReady) {
if (ExpectGLStringsToEverGetInitialized()) {
mMonitor.Wait();
} else {
// we'll never get notified, so don't wait. Just go on
// with empty GL strings.
mReady = true;
}
}
nsRefPtr<gl::GLContext> gl = gl::GLContextProvider::CreateOffscreen(
gfxIntSize(1, 1),
gfx::SurfaceCaps::ForRGB());
gl->MakeCurrent();
const char *spoofedVendor = PR_GetEnv("MOZ_GFX_SPOOF_GL_VENDOR");
if (spoofedVendor)
mVendor.Assign(spoofedVendor);
else
mVendor.Assign((const char*)gl->fGetString(LOCAL_GL_VENDOR));
const char *spoofedRenderer = PR_GetEnv("MOZ_GFX_SPOOF_GL_RENDERER");
if (spoofedRenderer)
mRenderer.Assign(spoofedRenderer);
else
mRenderer.Assign((const char*)gl->fGetString(LOCAL_GL_RENDERER));
const char *spoofedVersion = PR_GetEnv("MOZ_GFX_SPOOF_GL_VERSION");
if (spoofedVersion)
mVersion.Assign(spoofedVersion);
else
mVersion.Assign((const char*)gl->fGetString(LOCAL_GL_VERSION));
mReady = true;
}
}
void Initialize(gl::GLContext *gl) {
MonitorAutoLock autoLock(mMonitor);
MOZ_ASSERT(!mReady); // Initialize should be called only once
gl->MakeCurrent();
const char *spoofedVendor = PR_GetEnv("MOZ_GFX_SPOOF_GL_VENDOR");
if (spoofedVendor)
mVendor.Assign(spoofedVendor);
else
mVendor.Assign((const char*)gl->fGetString(LOCAL_GL_VENDOR));
const char *spoofedRenderer = PR_GetEnv("MOZ_GFX_SPOOF_GL_RENDERER");
if (spoofedRenderer)
mRenderer.Assign(spoofedRenderer);
else
mRenderer.Assign((const char*)gl->fGetString(LOCAL_GL_RENDERER));
const char *spoofedVersion = PR_GetEnv("MOZ_GFX_SPOOF_GL_VERSION");
if (spoofedVersion)
mVersion.Assign(spoofedVersion);
else
mVersion.Assign((const char*)gl->fGetString(LOCAL_GL_VERSION));
mReady = true;
mMonitor.Notify();
}
};
#ifdef DEBUG
@ -167,11 +133,6 @@ GfxInfo::GetCleartypeParameters(nsAString & aCleartypeParams)
return NS_ERROR_FAILURE;
}
void GfxInfo::InitializeGLStrings(gl::GLContext* gl)
{
mGLStrings->Initialize(gl);
}
void
GfxInfo::EnsureInitialized()
{
@ -403,10 +364,8 @@ GfxInfo::GetFeatureStatusImpl(int32_t aFeature,
*aOS = os;
// OpenGL layers are never blacklisted on Android.
// This early return is not just an optimization, it is actually
// important to avoid calling EnsureInitialized() below, as that would
// cause waiting for GL strings, which are going to be provided
// by the compositor's OpenGL context, so we'd deadlock.
// This early return is so we avoid potentially slow
// GLStrings initialization on startup when we initialize GL layers.
if (aFeature == nsIGfxInfo::FEATURE_OPENGL_LAYERS) {
*aStatus = nsIGfxInfo::FEATURE_NO_INFO;
return NS_OK;

View File

@ -66,8 +66,6 @@ public:
virtual uint32_t OperatingSystemVersion() MOZ_OVERRIDE;
virtual void InitializeGLStrings(gl::GLContext* gl);
protected:
virtual nsresult GetFeatureStatusImpl(int32_t aFeature,

View File

@ -15,7 +15,6 @@ EXPORTS += [
'AndroidJavaWrappers.h',
'AndroidJNIWrapper.h',
'GeneratedJNIWrappers.h',
'GfxInfo.h',
]
SOURCES += [