Bug 805939: Wait for shadow trees to update orientation before recompositing. r=cjones

This commit is contained in:
Chiajung Hung 2012-11-22 10:40:57 +08:00
parent 4430275e7a
commit 34d6df648e
19 changed files with 208 additions and 33 deletions

View File

@ -615,3 +615,6 @@ pref("memory.free_dirty_pages", true);
// UAProfile settings
pref("wap.UAProf.url", "");
pref("wap.UAProf.tagname", "x-wap-profile");
// Wait up to this much milliseconds when orientation changed
pref("layers.orientation.sync.timeout", 1000);

View File

@ -5,8 +5,6 @@
#ifndef mozilla_dom_ScreenOrientation_h
#define mozilla_dom_ScreenOrientation_h
#include "ipc/IPCMessageUtils.h"
namespace mozilla {
namespace dom {

View File

@ -94,6 +94,7 @@ LOCAL_INCLUDES += \
-I$(topsrcdir)/widget/xpwidgets \
-I$(topsrcdir)/dom/bluetooth \
-I$(topsrcdir)/dom/bluetooth/ipc \
-I$(topsrcdir)/hal \
$(NULL)
DEFINES += -DBIN_SUFFIX='"$(BIN_SUFFIX)"'

View File

@ -20,6 +20,7 @@ include "gfxMatrix.h";
include "FrameMetrics.h";
include "IPC/nsGUIEventIPC.h";
include "mozilla/dom/TabMessageUtils.h";
include "mozilla/dom/ScreenOrientation.h";
include "mozilla/dom/PermissionMessageUtils.h";
include "mozilla/layout/RenderFrameUtils.h";
@ -47,6 +48,7 @@ using nsSelectionEvent;
using nsTextEvent;
using nsTouchEvent;
using RemoteDOMEvent;
using mozilla::dom::ScreenOrientation;
namespace mozilla {
namespace dom {
@ -288,7 +290,7 @@ child:
LoadURL(nsCString uri);
UpdateDimensions(nsRect rect, nsIntSize size) compress;
UpdateDimensions(nsRect rect, nsIntSize size, ScreenOrientation orientation) compress;
UpdateFrame(FrameMetrics frame) compress;

View File

@ -168,6 +168,7 @@ TabChild::TabChild(const TabContext& aContext, uint32_t aChromeFlags)
, mNotified(false)
, mContentDocumentIsDisplayed(false)
, mTriedBrowserInit(false)
, mOrientation(eScreenOrientation_PortraitPrimary)
{
printf("creating %d!\n", NS_IsMainThread());
}
@ -1119,7 +1120,7 @@ TabChild::RecvShow(const nsIntSize& size)
}
bool
TabChild::RecvUpdateDimensions(const nsRect& rect, const nsIntSize& size)
TabChild::RecvUpdateDimensions(const nsRect& rect, const nsIntSize& size, const ScreenOrientation& orientation)
{
if (!mRemoteFrame) {
return true;
@ -1130,6 +1131,7 @@ TabChild::RecvUpdateDimensions(const nsRect& rect, const nsIntSize& size)
mOuterRect.width = rect.width;
mOuterRect.height = rect.height;
mOrientation = orientation;
mInnerSize = size;
mWidget->Resize(0, 0, size.width, size.height,
true);

View File

@ -197,7 +197,7 @@ public:
virtual bool RecvLoadURL(const nsCString& uri);
virtual bool RecvShow(const nsIntSize& size);
virtual bool RecvUpdateDimensions(const nsRect& rect, const nsIntSize& size);
virtual bool RecvUpdateDimensions(const nsRect& rect, const nsIntSize& size, const ScreenOrientation& orientation);
virtual bool RecvUpdateFrame(const mozilla::layers::FrameMetrics& aFrameMetrics);
virtual bool RecvHandleDoubleTap(const nsIntPoint& aPoint);
virtual bool RecvHandleSingleTap(const nsIntPoint& aPoint);
@ -291,6 +291,8 @@ public:
gfxSize GetZoom() { return mLastMetrics.mZoom; }
ScreenOrientation GetOrientation() { return mOrientation; }
void SetBackgroundColor(const nscolor& aColor);
void NotifyPainted();
@ -417,6 +419,7 @@ private:
bool mContentDocumentIsDisplayed;
bool mTriedBrowserInit;
nsString mAppType;
ScreenOrientation mOrientation;
DISALLOW_EVIL_CONSTRUCTORS(TabChild);
};

View File

@ -51,6 +51,7 @@
#include "nsThreadUtils.h"
#include "StructuredCloneUtils.h"
#include "TabChild.h"
#include "Hal.h"
using namespace mozilla::dom;
using namespace mozilla::ipc;
@ -256,7 +257,10 @@ TabParent::UpdateDimensions(const nsRect& rect, const nsIntSize& size)
if (mIsDestroyed) {
return;
}
unused << SendUpdateDimensions(rect, size);
hal::ScreenConfiguration config;
hal::GetCurrentScreenConfiguration(&config);
unused << SendUpdateDimensions(rect, size, config.orientation());
if (RenderFrameParent* rfp = GetRenderFrame()) {
rfp->NotifyDimensionsChanged(size.width, size.height);
}

View File

@ -199,6 +199,7 @@ include $(topsrcdir)/ipc/chromium/chromium-config.mk
LOCAL_INCLUDES += \
-I$(topsrcdir)/content/events/src \
-I$(topsrcdir)/hal \
-I$(ANDROID_SOURCE)/frameworks/base/include/media/stagefright \
-I$(ANDROID_SOURCE)/frameworks/base/include/media/stagefright/openmax \
$(NULL)

View File

@ -15,6 +15,7 @@
#include "nsXULAppAPI.h"
#include "RenderTrace.h"
#include "sampler.h"
#include "Hal.h"
#define PIXMAN_DONT_DEFINE_STDINT
#include "pixman.h"
@ -1094,7 +1095,17 @@ BasicShadowLayerManager::BeginTransactionWithTarget(gfxContext* aTarget)
// don't signal a new transaction to ShadowLayerForwarder. Carry on adding
// to the previous transaction.
if (HasShadowManager()) {
ShadowLayerForwarder::BeginTransaction(mTargetBounds, mTargetRotation);
ScreenOrientation orientation;
nsIntRect clientBounds;
if (TabChild* window = mWidget->GetOwningTabChild()) {
orientation = window->GetOrientation();
} else {
hal::ScreenConfiguration currentConfig;
hal::GetCurrentScreenConfiguration(&currentConfig);
orientation = currentConfig.orientation();
}
mWidget->GetClientBounds(clientBounds);
ShadowLayerForwarder::BeginTransaction(mTargetBounds, mTargetRotation, clientBounds, orientation);
// If we're drawing on behalf of a context with async pan/zoom
// enabled, then the entire buffer of thebes layers might be

View File

@ -30,6 +30,7 @@
#endif
using namespace std;
using namespace mozilla::dom;
using namespace mozilla::gfx;
namespace mozilla {
@ -755,7 +756,9 @@ LayerManagerD3D10::Render(EndTransactionFlags aFlags)
PaintToTarget();
} else if (mBackBuffer) {
ShadowLayerForwarder::BeginTransaction(mWidget->GetNaturalBounds(),
ROTATION_0);
ROTATION_0,
mWidget->GetNaturalBounds(),
eScreenOrientation_LandscapePrimary);
nsIntRect contentRect = nsIntRect(0, 0, rect.width, rect.height);
if (!mRootForShadowTree) {

View File

@ -34,9 +34,14 @@
#include "AnimationCommon.h"
#include "nsAnimationManager.h"
#include "TiledLayerBuffer.h"
#include "gfxPlatform.h"
#include "mozilla/dom/ScreenOrientation.h"
#include "mozilla/AutoRestore.h"
using namespace base;
using namespace mozilla;
using namespace mozilla::ipc;
using namespace mozilla::dom;
using namespace std;
namespace mozilla {
@ -60,6 +65,7 @@ static MessageLoop* sCompositorLoop = nullptr;
struct LayerTreeState {
nsRefPtr<Layer> mRoot;
nsRefPtr<AsyncPanZoomController> mController;
TargetConfig mTargetConfig;
};
static uint8_t sPanZoomUserDataKey;
@ -172,6 +178,8 @@ CompositorParent::CompositorParent(nsIWidget* aWidget,
, mEGLSurfaceSize(aSurfaceWidth, aSurfaceHeight)
, mPauseCompositionMonitor("PauseCompositionMonitor")
, mResumeCompositionMonitor("ResumeCompositionMonitor")
, mForceCompositionTask(nullptr)
, mOverrideComposeReadiness(false)
{
NS_ABORT_IF_FALSE(sCompositorThread != nullptr || sCompositorThreadID,
"The compositor thread must be Initialized before instanciating a COmpositorParent.");
@ -346,6 +354,14 @@ CompositorParent::ResumeComposition()
lock.NotifyAll();
}
void
CompositorParent::ForceComposition()
{
// Cancel the orientation changed state to force composition
mForceCompositionTask = nullptr;
ScheduleRenderOnCompositorThread();
}
void
CompositorParent::SetEGLSurfaceSize(int width, int height)
{
@ -469,12 +485,15 @@ public:
* guaranteed by this helper only being used during the drawing
* phase.
*/
AutoResolveRefLayers(Layer* aRoot) : mRoot(aRoot)
AutoResolveRefLayers(Layer* aRoot, const TargetConfig& aConfig) : mRoot(aRoot), mTargetConfig(aConfig), mReadyForCompose(true)
{ WalkTheTree<Resolve>(mRoot, nullptr); }
~AutoResolveRefLayers()
{ WalkTheTree<Detach>(mRoot, nullptr); }
bool IsReadyForCompose()
{ return mReadyForCompose; }
private:
enum Op { Resolve, Detach };
template<Op OP>
@ -482,20 +501,29 @@ private:
{
if (RefLayer* ref = aLayer->AsRefLayer()) {
if (const LayerTreeState* state = GetIndirectShadowTree(ref->GetReferentId())) {
if (Layer* referent = state->mRoot) {
if (OP == Resolve) {
ref->ConnectReferentLayer(referent);
if (AsyncPanZoomController* apzc = state->mController) {
referent->SetUserData(&sPanZoomUserDataKey,
new PanZoomUserData(apzc));
} else {
CompensateForContentScrollOffset(ref, referent);
}
} else {
ref->DetachReferentLayer(referent);
referent->RemoveUserData(&sPanZoomUserDataKey);
Layer* referent = state->mRoot;
if (!ref->GetVisibleRegion().IsEmpty()) {
ScreenOrientation chromeOrientation = mTargetConfig.orientation();
ScreenOrientation contentOrientation = state->mTargetConfig.orientation();
if (!IsSameDimension(chromeOrientation, contentOrientation) &&
ContentMightReflowOnOrientationChange(mTargetConfig.clientBounds())) {
mReadyForCompose = false;
}
}
if (OP == Resolve) {
ref->ConnectReferentLayer(referent);
if (AsyncPanZoomController* apzc = state->mController) {
referent->SetUserData(&sPanZoomUserDataKey,
new PanZoomUserData(apzc));
} else {
CompensateForContentScrollOffset(ref, referent);
}
} else {
ref->DetachReferentLayer(referent);
referent->RemoveUserData(&sPanZoomUserDataKey);
}
}
}
for (Layer* child = aLayer->GetFirstChild();
@ -529,7 +557,19 @@ private:
aContainer->AsShadowLayer()->SetShadowTransform(m);
}
bool IsSameDimension(ScreenOrientation o1, ScreenOrientation o2) {
bool isO1portrait = (o1 == eScreenOrientation_PortraitPrimary || o1 == eScreenOrientation_PortraitSecondary);
bool isO2portrait = (o2 == eScreenOrientation_PortraitPrimary || o2 == eScreenOrientation_PortraitSecondary);
return !(isO1portrait ^ isO2portrait);
}
bool ContentMightReflowOnOrientationChange(nsIntRect& rect) {
return rect.width != rect.height;
}
Layer* mRoot;
TargetConfig mTargetConfig;
bool mReadyForCompose;
AutoResolveRefLayers(const AutoResolveRefLayers&) MOZ_DELETE;
AutoResolveRefLayers& operator=(const AutoResolveRefLayers&) MOZ_DELETE;
@ -549,7 +589,15 @@ CompositorParent::Composite()
}
Layer* layer = mLayerManager->GetRoot();
AutoResolveRefLayers resolve(layer);
AutoResolveRefLayers resolve(layer, mTargetConfig);
if (mForceCompositionTask && !mOverrideComposeReadiness) {
if (!resolve.IsReadyForCompose()) {
return;
} else {
mForceCompositionTask->Cancel();
mForceCompositionTask = nullptr;
}
}
bool requestNextFrame = TransformShadowTree(mLastCompose);
if (requestNextFrame) {
@ -578,9 +626,13 @@ CompositorParent::Composite()
void
CompositorParent::ComposeToTarget(gfxContext* aTarget)
{
AutoRestore<bool> override(mOverrideComposeReadiness);
mOverrideComposeReadiness = true;
if (!CanComposite()) {
return;
}
mLayerManager->BeginTransactionWithTarget(aTarget);
// Since CanComposite() is true, Composite() must end the layers txn
// we opened above.
@ -990,6 +1042,22 @@ CompositorParent::ShadowLayersUpdated(ShadowLayersParent* aLayerTree,
const TargetConfig& aTargetConfig,
bool isFirstPaint)
{
if (!isFirstPaint && !mIsFirstPaint && mTargetConfig.orientation() != aTargetConfig.orientation()) {
if (mForceCompositionTask != NULL) {
mForceCompositionTask->Cancel();
}
mForceCompositionTask = NewRunnableMethod(this, &CompositorParent::ForceComposition);
ScheduleTask(mForceCompositionTask, gfxPlatform::GetPlatform()->GetOrientationSyncMillis());
}
// Instruct the LayerManager to update its render bounds now. Since all the orientation
// change, dimension change would be done at the stage, update the size here is free of
// race condition.
if (LAYERS_OPENGL == mLayerManager->GetBackendType()) {
LayerManagerOGL* lm = static_cast<LayerManagerOGL*>(mLayerManager.get());
lm->UpdateRenderBounds(aTargetConfig.clientBounds());
}
mTargetConfig = aTargetConfig;
mIsFirstPaint = mIsFirstPaint || isFirstPaint;
mLayersUpdated = true;
@ -1252,9 +1320,10 @@ CompositorParent::Create(Transport* aTransport, ProcessId aOtherProcess)
}
static void
UpdateIndirectTree(uint64_t aId, Layer* aRoot, bool isFirstPaint)
UpdateIndirectTree(uint64_t aId, Layer* aRoot, const TargetConfig& aTargetConfig, bool isFirstPaint)
{
sIndirectLayerTrees[aId].mRoot = aRoot;
sIndirectLayerTrees[aId].mTargetConfig = aTargetConfig;
if (ContainerLayer* root = aRoot->AsContainerLayer()) {
if (AsyncPanZoomController* apzc = sIndirectLayerTrees[aId].mController) {
apzc->NotifyLayersUpdated(root->GetFrameMetrics(), isFirstPaint);
@ -1321,7 +1390,7 @@ CrossProcessCompositorParent::ShadowLayersUpdated(
if (shadowRoot) {
SetShadowProperties(shadowRoot);
}
UpdateIndirectTree(id, shadowRoot, isFirstPaint);
UpdateIndirectTree(id, shadowRoot, aTargetConfig, isFirstPaint);
sCurrentCompositor->NotifyShadowTreeTransaction();
}

View File

@ -58,6 +58,7 @@ class CompositorParent : public PCompositorParent,
public ShadowLayersManager
{
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CompositorParent)
public:
CompositorParent(nsIWidget* aWidget,
bool aRenderToEGLSurface = false,
@ -180,6 +181,7 @@ private:
void PauseComposition();
void ResumeComposition();
void ResumeCompositionAndResize(int width, int height);
void ForceComposition();
// Sample transforms for layer trees. Return true to request
// another animation frame.
@ -291,6 +293,9 @@ private:
uint64_t mCompositorID;
bool mOverrideComposeReadiness;
CancelableTask* mForceCompositionTask;
DISALLOW_EVIL_CONSTRUCTORS(CompositorParent);
};

View File

@ -14,6 +14,7 @@ include protocol PRenderFrame;
include "gfxipc/ShadowLayerUtils.h";
include "mozilla/WidgetUtils.h";
include "mozilla/TimeStamp.h";
include "mozilla/dom/ScreenOrientation.h";
include "nsCSSProperty.h";
using gfxPoint3D;
@ -24,6 +25,7 @@ using mozilla::TimeDuration;
using mozilla::TimeStamp;
using mozilla::ScreenRotation;
using nsCSSProperty;
using mozilla::dom::ScreenOrientation;
/**
* The layers protocol is spoken between thread contexts that manage
@ -39,6 +41,8 @@ namespace layers {
struct TargetConfig {
nsIntRect naturalBounds;
ScreenRotation rotation;
nsIntRect clientBounds;
ScreenOrientation orientation;
};
// Create a shadow layer for |layer|

View File

@ -25,6 +25,7 @@
using namespace mozilla::ipc;
using namespace mozilla::gl;
using namespace mozilla::dom;
namespace mozilla {
namespace layers {
@ -42,7 +43,8 @@ public:
, mRotationChanged(false)
{}
void Begin(const nsIntRect& aTargetBounds, ScreenRotation aRotation)
void Begin(const nsIntRect& aTargetBounds, ScreenRotation aRotation,
const nsIntRect& aClientBounds, ScreenOrientation aOrientation)
{
mOpen = true;
mTargetBounds = aTargetBounds;
@ -50,6 +52,8 @@ public:
mRotationChanged = true;
}
mTargetRotation = aRotation;
mClientBounds = aClientBounds;
mTargetOrientation = aOrientation;
}
void AddEdit(const Edit& aEdit)
@ -107,6 +111,8 @@ public:
ShadowableLayerSet mMutants;
nsIntRect mTargetBounds;
ScreenRotation mTargetRotation;
nsIntRect mClientBounds;
ScreenOrientation mTargetOrientation;
bool mSwapRequired;
private:
@ -140,11 +146,13 @@ ShadowLayerForwarder::~ShadowLayerForwarder()
void
ShadowLayerForwarder::BeginTransaction(const nsIntRect& aTargetBounds,
ScreenRotation aRotation)
ScreenRotation aRotation,
const nsIntRect& aClientBounds,
ScreenOrientation aOrientation)
{
NS_ABORT_IF_FALSE(HasShadowManager(), "no manager to forward to");
NS_ABORT_IF_FALSE(mTxn->Finished(), "uncommitted txn?");
mTxn->Begin(aTargetBounds, aRotation);
mTxn->Begin(aTargetBounds, aRotation, aClientBounds, aOrientation);
}
static PLayerChild*
@ -358,7 +366,7 @@ ShadowLayerForwarder::EndTransaction(InfallibleTArray<EditReply>* aReplies)
cset.AppendElements(&mTxn->mPaints.front(), mTxn->mPaints.size());
}
TargetConfig targetConfig(mTxn->mTargetBounds, mTxn->mTargetRotation);
TargetConfig targetConfig(mTxn->mTargetBounds, mTxn->mTargetRotation, mTxn->mClientBounds, mTxn->mTargetOrientation);
MOZ_LAYERS_LOG(("[LayersForwarder] syncing before send..."));
PlatformSyncBeforeUpdate();

View File

@ -14,6 +14,7 @@
#include "ImageLayers.h"
#include "mozilla/ipc/SharedMemory.h"
#include "mozilla/WidgetUtils.h"
#include "mozilla/dom/ScreenOrientation.h"
class gfxSharedImageSurface;
@ -116,7 +117,9 @@ public:
* ShadowLayerManager.
*/
void BeginTransaction(const nsIntRect& aTargetBounds,
ScreenRotation aRotation);
ScreenRotation aRotation,
const nsIntRect& aClientBounds,
mozilla::dom::ScreenOrientation aOrientation);
/**
* The following methods may only be called after BeginTransaction()

View File

@ -1037,10 +1037,14 @@ LayerManagerOGL::Render()
if (mIsRenderingToEGLSurface) {
rect = nsIntRect(0, 0, mSurfaceSize.width, mSurfaceSize.height);
} else {
// FIXME/bug XXXXXX this races with rotation changes on the main
// thread, and undoes all the care we take with layers txns being
// sent atomically with rotation changes
mWidget->GetClientBounds(rect);
rect = mRenderBounds;
// If render bounds is not updated explicitly, try to infer it from widget
if (rect.width == 0 || rect.height == 0) {
// FIXME/bug XXXXXX this races with rotation changes on the main
// thread, and undoes all the care we take with layers txns being
// sent atomically with rotation changes
mWidget->GetClientBounds(rect);
}
}
WorldTransformRect(rect);
@ -1265,6 +1269,12 @@ LayerManagerOGL::WorldTransformRect(nsIntRect& aRect)
aRect.SetRect(grect.X(), grect.Y(), grect.Width(), grect.Height());
}
void
LayerManagerOGL::UpdateRenderBounds(const nsIntRect& aRect)
{
mRenderBounds = aRect;
}
void
LayerManagerOGL::SetSurfaceSize(int width, int height)
{

View File

@ -290,6 +290,8 @@ public:
gfxMatrix& GetWorldTransform(void);
void WorldTransformRect(nsIntRect& aRect);
void UpdateRenderBounds(const nsIntRect& aRect);
/**
* Set the size of the surface we're rendering to.
*/
@ -414,6 +416,7 @@ private:
void *mThebesLayerCallbackData;
gfxMatrix mWorldMatrix;
nsAutoPtr<FPSState> mFPS;
nsIntRect mRenderBounds;
#ifdef DEBUG
// NB: only interesting when this is a purely compositing layer
// manager. True after possibly onscreen layers have had their

View File

@ -174,7 +174,29 @@ FontPrefsObserver::Observe(nsISupports *aSubject,
return NS_OK;
}
class OrientationSyncPrefsObserver : public nsIObserver
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIOBSERVER
};
NS_IMPL_ISUPPORTS1(OrientationSyncPrefsObserver, nsIObserver)
NS_IMETHODIMP
OrientationSyncPrefsObserver::Observe(nsISupports *aSubject,
const char *aTopic,
const PRUnichar *someData)
{
if (!someData) {
NS_ERROR("orientation sync pref observer broken");
return NS_ERROR_UNEXPECTED;
}
NS_ASSERTION(gfxPlatform::GetPlatform(), "the singleton instance has gone");
gfxPlatform::GetPlatform()->OrientationSyncPrefsObserverChanged();
return NS_OK;
}
// this needs to match the list of pref font.default.xx entries listed in all.js!
// the order *must* match the order in eFontPrefLang
@ -338,6 +360,9 @@ gfxPlatform::Init()
gPlatform->mFontPrefsObserver = new FontPrefsObserver();
Preferences::AddStrongObservers(gPlatform->mFontPrefsObserver, kObservedPrefs);
gPlatform->mOrientationSyncPrefsObserver = new OrientationSyncPrefsObserver();
Preferences::AddStrongObserver(gPlatform->mOrientationSyncPrefsObserver, "layers.orientation.sync.timeout");
gPlatform->mWorkAroundDriverBugs = Preferences::GetBool("gfx.work-around-driver-bugs", true);
mozilla::Preferences::AddBoolVarCache(&gPlatform->mWidgetUpdateFlashing,
@ -359,6 +384,8 @@ gfxPlatform::Init()
gPlatform->mRecorder = Factory::CreateEventRecorderForFile("browserrecording.aer");
Factory::SetGlobalEventRecorder(gPlatform->mRecorder);
}
gPlatform->mOrientationSyncMillis = Preferences::GetUint("layers.orientation.sync.timeout", (uint32_t)0);
}
void
@ -1699,3 +1726,15 @@ gfxPlatform::OptimalFormatForContent(gfxASurface::gfxContentType aContent)
return gfxASurface::ImageFormatARGB32;
}
}
void
gfxPlatform::OrientationSyncPrefsObserverChanged()
{
mOrientationSyncMillis = Preferences::GetUint("layers.orientation.sync.timeout", (uint32_t)0);
}
uint32_t
gfxPlatform::GetOrientationSyncMillis() const
{
return mOrientationSyncMillis;
}

View File

@ -469,6 +469,8 @@ public:
virtual void FontsPrefsChanged(const char *aPref);
void OrientationSyncPrefsObserverChanged();
int32_t GetBidiNumeralOption();
/**
@ -495,6 +497,8 @@ public:
bool WidgetUpdateFlashing() const { return mWidgetUpdateFlashing; }
uint32_t GetOrientationSyncMillis() const;
protected:
gfxPlatform();
virtual ~gfxPlatform();
@ -576,6 +580,7 @@ private:
nsTArray<uint32_t> mCJKPrefLangs;
nsCOMPtr<nsIObserver> mSRGBOverrideObserver;
nsCOMPtr<nsIObserver> mFontPrefsObserver;
nsCOMPtr<nsIObserver> mOrientationSyncPrefsObserver;
// The preferred draw target backend to use for canvas
mozilla::gfx::BackendType mPreferredCanvasBackend;
@ -589,6 +594,7 @@ private:
mozilla::RefPtr<mozilla::gfx::DrawEventRecorder> mRecorder;
bool mWidgetUpdateFlashing;
uint32_t mOrientationSyncMillis;
};
#endif /* GFX_PLATFORM_H */