This commit is contained in:
Kyle Huey 2012-04-25 20:22:53 -07:00
Родитель c7b142891c b52701d351
Коммит 2751180900
116 изменённых файлов: 2610 добавлений и 1964 удалений

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

@ -38,7 +38,7 @@
*
* ***** END LICENSE BLOCK ***** */
#include "nsApplicationAccessibleWrap.h"
#include "ApplicationAccessibleWrap.h"
#include "nsCOMPtr.h"
#include "nsMai.h"
@ -466,25 +466,19 @@ mai_util_remove_key_event_listener (guint remove_listener)
}
}
AtkObject *
AtkObject*
mai_util_get_root(void)
{
if (nsAccessibilityService::IsShutdown()) {
// We've shutdown, try to use gail instead
// (to avoid assert in spi_atk_tidy_windows())
if (gail_get_root)
return gail_get_root();
return nsnull;
}
nsApplicationAccessible *applicationAcc =
nsAccessNode::GetApplicationAccessible();
if (applicationAcc)
return applicationAcc->GetAtkObject();
if (nsAccessibilityService::IsShutdown()) {
// We've shutdown, try to use gail instead
// (to avoid assert in spi_atk_tidy_windows())
if (gail_get_root)
return gail_get_root();
return nsnull;
}
return nsAccessNode::GetApplicationAccessible()->GetAtkObject();
}
G_CONST_RETURN gchar *
@ -550,15 +544,15 @@ add_listener (GSignalEmissionHook listener,
static nsresult LoadGtkModule(GnomeAccessibilityModule& aModule);
// nsApplicationAccessibleWrap
// ApplicationAccessibleWrap
nsApplicationAccessibleWrap::nsApplicationAccessibleWrap():
nsApplicationAccessible()
ApplicationAccessibleWrap::ApplicationAccessibleWrap():
ApplicationAccessible()
{
MAI_LOG_DEBUG(("======Create AppRootAcc=%p\n", (void*)this));
MAI_LOG_DEBUG(("======Create AppRootAcc=%p\n", (void*)this));
}
nsApplicationAccessibleWrap::~nsApplicationAccessibleWrap()
ApplicationAccessibleWrap::~ApplicationAccessibleWrap()
{
MAI_LOG_DEBUG(("======Destory AppRootAcc=%p\n", (void*)this));
nsAccessibleWrap::ShutdownAtkObject();
@ -613,7 +607,7 @@ toplevel_event_watcher(GSignalInvocationHint* ihint,
}
bool
nsApplicationAccessibleWrap::Init()
ApplicationAccessibleWrap::Init()
{
if (ShouldA11yBeEnabled()) {
// load and initialize gail library
@ -655,11 +649,11 @@ nsApplicationAccessibleWrap::Init()
}
}
return nsApplicationAccessible::Init();
return ApplicationAccessible::Init();
}
void
nsApplicationAccessibleWrap::Unload()
ApplicationAccessibleWrap::Unload()
{
if (sToplevel_event_hook_added) {
sToplevel_event_hook_added = false;
@ -697,7 +691,7 @@ nsApplicationAccessibleWrap::Unload()
}
NS_IMETHODIMP
nsApplicationAccessibleWrap::GetName(nsAString& aName)
ApplicationAccessibleWrap::GetName(nsAString& aName)
{
// ATK doesn't provide a way to obtain an application name (for example,
// Firefox or Thunderbird) like IA2 does. Thus let's return an application
@ -707,7 +701,7 @@ nsApplicationAccessibleWrap::GetName(nsAString& aName)
}
NS_IMETHODIMP
nsApplicationAccessibleWrap::GetNativeInterface(void **aOutAccessible)
ApplicationAccessibleWrap::GetNativeInterface(void** aOutAccessible)
{
*aOutAccessible = nsnull;
@ -745,9 +739,9 @@ gboolean fireRootAccessibleAddedCB(gpointer data)
}
bool
nsApplicationAccessibleWrap::AppendChild(nsAccessible *aChild)
ApplicationAccessibleWrap::AppendChild(nsAccessible* aChild)
{
if (!nsApplicationAccessible::AppendChild(aChild))
if (!ApplicationAccessible::AppendChild(aChild))
return false;
AtkObject *atkAccessible = nsAccessibleWrap::GetAtkObject(aChild);
@ -772,7 +766,7 @@ nsApplicationAccessibleWrap::AppendChild(nsAccessible *aChild)
}
bool
nsApplicationAccessibleWrap::RemoveChild(nsAccessible* aChild)
ApplicationAccessibleWrap::RemoveChild(nsAccessible* aChild)
{
PRInt32 index = aChild->IndexInParent();
@ -781,11 +775,11 @@ nsApplicationAccessibleWrap::RemoveChild(nsAccessible* aChild)
g_signal_emit_by_name(mAtkObject, "children_changed::remove", index,
atkAccessible, NULL);
return nsApplicationAccessible::RemoveChild(aChild);
return ApplicationAccessible::RemoveChild(aChild);
}
void
nsApplicationAccessibleWrap::PreCreate()
ApplicationAccessibleWrap::PreCreate()
{
if (!sATKChecked) {
sATKLib = PR_LoadLibrary(sATKLibName);

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

@ -38,20 +38,20 @@
*
* ***** END LICENSE BLOCK ***** */
#ifndef __NS_APP_ROOT_ACCESSIBLE_H__
#define __NS_APP_ROOT_ACCESSIBLE_H__
#ifndef MOZILLA_A11Y_APPLICATION_ACCESSIBLE_WRAP_H__
#define MOZILLA_A11Y_APPLICATION_ACCESSIBLE_WRAP_H__
#include "nsApplicationAccessible.h"
#include "ApplicationAccessible.h"
class nsApplicationAccessibleWrap: public nsApplicationAccessible
class ApplicationAccessibleWrap: public ApplicationAccessible
{
public:
static void Unload();
static void PreCreate();
public:
nsApplicationAccessibleWrap();
virtual ~nsApplicationAccessibleWrap();
ApplicationAccessibleWrap();
virtual ~ApplicationAccessibleWrap();
// nsAccessNode
virtual bool Init();

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

@ -53,7 +53,7 @@ CPPSRCS = \
nsAccessibleWrap.cpp \
nsDocAccessibleWrap.cpp \
nsRootAccessibleWrap.cpp \
nsApplicationAccessibleWrap.cpp \
ApplicationAccessibleWrap.cpp \
nsMaiInterfaceComponent.cpp \
nsMaiInterfaceAction.cpp \
nsMaiInterfaceText.cpp \

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

@ -38,7 +38,6 @@
* ***** END LICENSE BLOCK ***** */
#include "nsAccessNodeWrap.h"
#include "nsApplicationAccessibleWrap.h"
/* For documentation of the accessibility architecture,
* see http://lxr.mozilla.org/seamonkey/source/accessible/accessible-docs.html

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

@ -41,9 +41,9 @@
#include "nsAccessibleWrap.h"
#include "Accessible-inl.h"
#include "ApplicationAccessibleWrap.h"
#include "InterfaceInitFuncs.h"
#include "nsAccUtils.h"
#include "nsApplicationAccessibleWrap.h"
#include "nsIAccessibleRelation.h"
#include "nsRootAccessible.h"
#include "nsDocAccessibleWrap.h"
@ -68,7 +68,7 @@ using namespace mozilla::a11y;
nsAccessibleWrap::EAvailableAtkSignals nsAccessibleWrap::gAvailableAtkSignals =
eUnknown;
//defined in nsApplicationAccessibleWrap.cpp
//defined in ApplicationAccessibleWrap.cpp
extern "C" GType g_atk_hyperlink_impl_type;
/* MaiAtkObject */
@ -976,25 +976,20 @@ refRelationSetCB(AtkObject *aAtkObj)
// for it.
nsAccessibleWrap *GetAccessibleWrap(AtkObject *aAtkObj)
{
NS_ENSURE_TRUE(IS_MAI_OBJECT(aAtkObj), nsnull);
nsAccessibleWrap *tmpAccWrap = MAI_ATK_OBJECT(aAtkObj)->accWrap;
NS_ENSURE_TRUE(IS_MAI_OBJECT(aAtkObj), nsnull);
nsAccessibleWrap* accWrap = MAI_ATK_OBJECT(aAtkObj)->accWrap;
// Check if AccessibleWrap was deconstructed
if (tmpAccWrap == nsnull) {
return nsnull;
}
// Check if the accessible was deconstructed.
if (!accWrap)
return nsnull;
NS_ENSURE_TRUE(tmpAccWrap->GetAtkObject() == aAtkObj, nsnull);
NS_ENSURE_TRUE(accWrap->GetAtkObject() == aAtkObj, nsnull);
nsApplicationAccessible *applicationAcc =
nsAccessNode::GetApplicationAccessible();
nsAccessibleWrap* tmpAppAccWrap =
static_cast<nsAccessibleWrap*>(applicationAcc);
nsAccessibleWrap* appAccWrap = nsAccessNode::GetApplicationAccessible();
if (appAccWrap != accWrap && !accWrap->IsValidObject())
return nsnull;
if (tmpAppAccWrap != tmpAccWrap && !tmpAccWrap->IsValidObject())
return nsnull;
return tmpAccWrap;
return accWrap;
}
nsresult

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

@ -39,9 +39,9 @@
#include "AccEvent.h"
#include "ApplicationAccessibleWrap.h"
#include "nsAccessibilityService.h"
#include "nsAccUtils.h"
#include "nsApplicationAccessibleWrap.h"
#include "nsDocAccessible.h"
#include "nsIAccessibleText.h"
#include "nsAccEvent.h"
@ -155,7 +155,7 @@ AccEvent::CaptureIsFromUserInput(EIsFromUserInput aIsFromUserInput)
// XXX: remove this hack during reorganization of 506907. Meanwhile we
// want to get rid an assertion for application accessible events which
// don't have DOM node (see bug 506206).
nsApplicationAccessible *applicationAcc =
ApplicationAccessible* applicationAcc =
nsAccessNode::GetApplicationAccessible();
if (mAccessible != static_cast<nsIAccessible*>(applicationAcc))

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

@ -69,7 +69,6 @@ CPPSRCS = \
nsBaseWidgetAccessible.cpp \
nsEventShell.cpp \
nsRootAccessible.cpp \
nsApplicationAccessible.cpp \
nsCaretAccessible.cpp \
nsTextAccessible.cpp \
nsTextEquivUtils.cpp \

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

@ -38,9 +38,9 @@
#include "nsAccDocManager.h"
#include "ApplicationAccessible.h"
#include "nsAccessibilityService.h"
#include "nsAccUtils.h"
#include "nsApplicationAccessible.h"
#include "nsARIAMap.h"
#include "nsRootAccessibleWrap.h"
#include "States.h"

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

@ -38,9 +38,9 @@
#include "nsAccessNode.h"
#include "ApplicationAccessibleWrap.h"
#include "nsAccessibilityService.h"
#include "nsAccUtils.h"
#include "nsApplicationAccessibleWrap.h"
#include "nsCoreUtils.h"
#include "nsRootAccessible.h"
@ -67,7 +67,7 @@ nsIStringBundle *nsAccessNode::gStringBundle = 0;
bool nsAccessNode::gIsFormFillEnabled = false;
nsApplicationAccessible *nsAccessNode::gApplicationAccessible = nsnull;
ApplicationAccessible* nsAccessNode::gApplicationAccessible = nsnull;
/*
* Class nsAccessNode
@ -130,18 +130,16 @@ nsAccessNode::Shutdown()
mDoc = nsnull;
}
nsApplicationAccessible*
ApplicationAccessible*
nsAccessNode::GetApplicationAccessible()
{
NS_ASSERTION(!nsAccessibilityService::IsShutdown(),
"Accessibility wasn't initialized!");
if (!gApplicationAccessible) {
nsApplicationAccessibleWrap::PreCreate();
ApplicationAccessibleWrap::PreCreate();
gApplicationAccessible = new nsApplicationAccessibleWrap();
if (!gApplicationAccessible)
return nsnull;
gApplicationAccessible = new ApplicationAccessibleWrap();
// Addref on create. Will Release in ShutdownXPAccessibility()
NS_ADDREF(gApplicationAccessible);
@ -200,7 +198,7 @@ void nsAccessNode::ShutdownXPAccessibility()
// Release gApplicationAccessible after everything else is shutdown
// so we don't accidently create it again while tearing down root accessibles
nsApplicationAccessibleWrap::Unload();
ApplicationAccessibleWrap::Unload();
if (gApplicationAccessible) {
gApplicationAccessible->Shutdown();
NS_RELEASE(gApplicationAccessible);

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

@ -53,8 +53,8 @@
#include "nsIStringBundle.h"
#include "nsWeakReference.h"
class ApplicationAccessible;
class nsAccessNode;
class nsApplicationAccessible;
class nsDocAccessible;
class nsIAccessibleDocument;
class nsRootAccessible;
@ -83,7 +83,7 @@ public:
/**
* Return an application accessible.
*/
static nsApplicationAccessible* GetApplicationAccessible();
static ApplicationAccessible* GetApplicationAccessible();
/**
* Return the document accessible for this access node.
@ -174,7 +174,7 @@ private:
nsAccessNode(const nsAccessNode&) MOZ_DELETE;
nsAccessNode& operator =(const nsAccessNode&) MOZ_DELETE;
static nsApplicationAccessible *gApplicationAccessible;
static ApplicationAccessible* gApplicationAccessible;
};
#endif

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

@ -40,6 +40,7 @@
// NOTE: alphabetically ordered
#include "Accessible-inl.h"
#include "ApplicationAccessibleWrap.h"
#include "ARIAGridAccessibleWrap.h"
#ifdef MOZ_ACCESSIBILITY_ATK
#include "AtkSocketAccessible.h"
@ -48,7 +49,6 @@
#include "nsAccessiblePivot.h"
#include "nsAccUtils.h"
#include "nsARIAMap.h"
#include "nsApplicationAccessibleWrap.h"
#include "nsIAccessibleProvider.h"
#include "nsHTMLCanvasAccessible.h"
#include "nsHTMLImageMapAccessible.h"
@ -678,7 +678,7 @@ nsAccessibilityService::RecreateAccessible(nsIPresShell* aPresShell,
// nsIAccessibleRetrieval
NS_IMETHODIMP
nsAccessibilityService::GetApplicationAccessible(nsIAccessible **aAccessibleApplication)
nsAccessibilityService::GetApplicationAccessible(nsIAccessible** aAccessibleApplication)
{
NS_ENSURE_ARG_POINTER(aAccessibleApplication);
@ -1724,7 +1724,7 @@ nsAccessible*
nsAccessibilityService::AddNativeRootAccessible(void* aAtkAccessible)
{
#ifdef MOZ_ACCESSIBILITY_ATK
nsApplicationAccessible* applicationAcc =
ApplicationAccessible* applicationAcc =
nsAccessNode::GetApplicationAccessible();
if (!applicationAcc)
return nsnull;
@ -1745,7 +1745,7 @@ void
nsAccessibilityService::RemoveNativeRootAccessible(nsAccessible* aAccessible)
{
#ifdef MOZ_ACCESSIBILITY_ATK
nsApplicationAccessible* applicationAcc =
ApplicationAccessible* applicationAcc =
nsAccessNode::GetApplicationAccessible();
if (applicationAcc)

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

@ -63,7 +63,7 @@ FocusManager* FocusMgr();
/**
* Perform initialization that should be done as soon as possible, in order
* to minimize startup time.
* XXX: this function and the next defined in nsApplicationAccessibleWrap.cpp
* XXX: this function and the next defined in ApplicationAccessibleWrap.cpp
*/
void PreInit();

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

@ -42,7 +42,6 @@
#include "Accessible-inl.h"
#include "nsAccessibilityService.h"
#include "nsApplicationAccessibleWrap.h"
#include "nsAccUtils.h"
#include "nsCoreUtils.h"
#include "Relation.h"

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

@ -40,7 +40,7 @@
*
* ***** END LICENSE BLOCK ***** */
#include "nsApplicationAccessible.h"
#include "ApplicationAccessible.h"
#include "nsAccessibilityService.h"
#include "nsAccUtils.h"
@ -57,7 +57,7 @@
using namespace mozilla::a11y;
nsApplicationAccessible::nsApplicationAccessible() :
ApplicationAccessible::ApplicationAccessible() :
nsAccessibleWrap(nsnull, nsnull)
{
mFlags |= eApplicationAccessible;
@ -66,14 +66,14 @@ nsApplicationAccessible::nsApplicationAccessible() :
////////////////////////////////////////////////////////////////////////////////
// nsISupports
NS_IMPL_ISUPPORTS_INHERITED1(nsApplicationAccessible, nsAccessible,
NS_IMPL_ISUPPORTS_INHERITED1(ApplicationAccessible, nsAccessible,
nsIAccessibleApplication)
////////////////////////////////////////////////////////////////////////////////
// nsIAccessible
NS_IMETHODIMP
nsApplicationAccessible::GetParent(nsIAccessible **aAccessible)
ApplicationAccessible::GetParent(nsIAccessible** aAccessible)
{
NS_ENSURE_ARG_POINTER(aAccessible);
*aAccessible = nsnull;
@ -81,7 +81,7 @@ nsApplicationAccessible::GetParent(nsIAccessible **aAccessible)
}
NS_IMETHODIMP
nsApplicationAccessible::GetNextSibling(nsIAccessible **aNextSibling)
ApplicationAccessible::GetNextSibling(nsIAccessible** aNextSibling)
{
NS_ENSURE_ARG_POINTER(aNextSibling);
*aNextSibling = nsnull;
@ -89,7 +89,7 @@ nsApplicationAccessible::GetNextSibling(nsIAccessible **aNextSibling)
}
NS_IMETHODIMP
nsApplicationAccessible::GetPreviousSibling(nsIAccessible **aPreviousSibling)
ApplicationAccessible::GetPreviousSibling(nsIAccessible** aPreviousSibling)
{
NS_ENSURE_ARG_POINTER(aPreviousSibling);
*aPreviousSibling = nsnull;
@ -97,7 +97,7 @@ nsApplicationAccessible::GetPreviousSibling(nsIAccessible **aPreviousSibling)
}
NS_IMETHODIMP
nsApplicationAccessible::GetName(nsAString& aName)
ApplicationAccessible::GetName(nsAString& aName)
{
aName.Truncate();
@ -125,25 +125,25 @@ nsApplicationAccessible::GetName(nsAString& aName)
}
void
nsApplicationAccessible::Description(nsString &aDescription)
ApplicationAccessible::Description(nsString& aDescription)
{
aDescription.Truncate();
}
void
nsApplicationAccessible::Value(nsString& aValue)
ApplicationAccessible::Value(nsString& aValue)
{
aValue.Truncate();
}
PRUint64
nsApplicationAccessible::State()
ApplicationAccessible::State()
{
return IsDefunct() ? states::DEFUNCT : 0;
}
NS_IMETHODIMP
nsApplicationAccessible::GetAttributes(nsIPersistentProperties **aAttributes)
ApplicationAccessible::GetAttributes(nsIPersistentProperties** aAttributes)
{
NS_ENSURE_ARG_POINTER(aAttributes);
*aAttributes = nsnull;
@ -151,9 +151,9 @@ nsApplicationAccessible::GetAttributes(nsIPersistentProperties **aAttributes)
}
NS_IMETHODIMP
nsApplicationAccessible::GroupPosition(PRInt32 *aGroupLevel,
PRInt32 *aSimilarItemsInGroup,
PRInt32 *aPositionInGroup)
ApplicationAccessible::GroupPosition(PRInt32* aGroupLevel,
PRInt32* aSimilarItemsInGroup,
PRInt32* aPositionInGroup)
{
NS_ENSURE_ARG_POINTER(aGroupLevel);
*aGroupLevel = 0;
@ -165,14 +165,14 @@ nsApplicationAccessible::GroupPosition(PRInt32 *aGroupLevel,
}
nsAccessible*
nsApplicationAccessible::ChildAtPoint(PRInt32 aX, PRInt32 aY,
EWhichChildAtPoint aWhichChild)
ApplicationAccessible::ChildAtPoint(PRInt32 aX, PRInt32 aY,
EWhichChildAtPoint aWhichChild)
{
return nsnull;
}
nsAccessible*
nsApplicationAccessible::FocusedChild()
ApplicationAccessible::FocusedChild()
{
nsAccessible* focus = FocusMgr()->FocusedAccessible();
if (focus && focus->Parent() == this)
@ -182,14 +182,14 @@ nsApplicationAccessible::FocusedChild()
}
Relation
nsApplicationAccessible::RelationByType(PRUint32 aRelationType)
ApplicationAccessible::RelationByType(PRUint32 aRelationType)
{
return Relation();
}
NS_IMETHODIMP
nsApplicationAccessible::GetBounds(PRInt32 *aX, PRInt32 *aY,
PRInt32 *aWidth, PRInt32 *aHeight)
ApplicationAccessible::GetBounds(PRInt32* aX, PRInt32* aY,
PRInt32* aWidth, PRInt32* aHeight)
{
NS_ENSURE_ARG_POINTER(aX);
*aX = 0;
@ -203,46 +203,46 @@ nsApplicationAccessible::GetBounds(PRInt32 *aX, PRInt32 *aY,
}
NS_IMETHODIMP
nsApplicationAccessible::SetSelected(bool aIsSelected)
ApplicationAccessible::SetSelected(bool aIsSelected)
{
return NS_OK;
}
NS_IMETHODIMP
nsApplicationAccessible::TakeSelection()
ApplicationAccessible::TakeSelection()
{
return NS_OK;
}
NS_IMETHODIMP
nsApplicationAccessible::TakeFocus()
ApplicationAccessible::TakeFocus()
{
return NS_OK;
}
PRUint8
nsApplicationAccessible::ActionCount()
ApplicationAccessible::ActionCount()
{
return 0;
}
NS_IMETHODIMP
nsApplicationAccessible::GetActionName(PRUint8 aIndex, nsAString &aName)
ApplicationAccessible::GetActionName(PRUint8 aIndex, nsAString& aName)
{
aName.Truncate();
return NS_ERROR_INVALID_ARG;
}
NS_IMETHODIMP
nsApplicationAccessible::GetActionDescription(PRUint8 aIndex,
nsAString &aDescription)
ApplicationAccessible::GetActionDescription(PRUint8 aIndex,
nsAString& aDescription)
{
aDescription.Truncate();
return NS_ERROR_INVALID_ARG;
}
NS_IMETHODIMP
nsApplicationAccessible::DoAction(PRUint8 aIndex)
ApplicationAccessible::DoAction(PRUint8 aIndex)
{
return NS_OK;
}
@ -251,7 +251,7 @@ nsApplicationAccessible::DoAction(PRUint8 aIndex)
// nsIAccessibleApplication
NS_IMETHODIMP
nsApplicationAccessible::GetAppName(nsAString& aName)
ApplicationAccessible::GetAppName(nsAString& aName)
{
aName.Truncate();
@ -267,7 +267,7 @@ nsApplicationAccessible::GetAppName(nsAString& aName)
}
NS_IMETHODIMP
nsApplicationAccessible::GetAppVersion(nsAString& aVersion)
ApplicationAccessible::GetAppVersion(nsAString& aVersion)
{
aVersion.Truncate();
@ -283,14 +283,14 @@ nsApplicationAccessible::GetAppVersion(nsAString& aVersion)
}
NS_IMETHODIMP
nsApplicationAccessible::GetPlatformName(nsAString& aName)
ApplicationAccessible::GetPlatformName(nsAString& aName)
{
aName.AssignLiteral("Gecko");
return NS_OK;
}
NS_IMETHODIMP
nsApplicationAccessible::GetPlatformVersion(nsAString& aVersion)
ApplicationAccessible::GetPlatformVersion(nsAString& aVersion)
{
aVersion.Truncate();
@ -309,20 +309,20 @@ nsApplicationAccessible::GetPlatformVersion(nsAString& aVersion)
// nsAccessNode public methods
bool
nsApplicationAccessible::Init()
ApplicationAccessible::Init()
{
mAppInfo = do_GetService("@mozilla.org/xre/app-info;1");
return true;
}
void
nsApplicationAccessible::Shutdown()
ApplicationAccessible::Shutdown()
{
mAppInfo = nsnull;
}
bool
nsApplicationAccessible::IsPrimaryForNode() const
ApplicationAccessible::IsPrimaryForNode() const
{
return false;
}
@ -331,31 +331,31 @@ nsApplicationAccessible::IsPrimaryForNode() const
// nsAccessible public methods
void
nsApplicationAccessible::ApplyARIAState(PRUint64* aState)
ApplicationAccessible::ApplyARIAState(PRUint64* aState)
{
}
role
nsApplicationAccessible::NativeRole()
ApplicationAccessible::NativeRole()
{
return roles::APP_ROOT;
}
PRUint64
nsApplicationAccessible::NativeState()
ApplicationAccessible::NativeState()
{
return 0;
}
void
nsApplicationAccessible::InvalidateChildren()
ApplicationAccessible::InvalidateChildren()
{
// Do nothing because application children are kept updated by AppendChild()
// and RemoveChild() method calls.
}
KeyBinding
nsApplicationAccessible::AccessKey() const
ApplicationAccessible::AccessKey() const
{
return KeyBinding();
}
@ -364,7 +364,7 @@ nsApplicationAccessible::AccessKey() const
// nsAccessible protected methods
void
nsApplicationAccessible::CacheChildren()
ApplicationAccessible::CacheChildren()
{
// CacheChildren is called only once for application accessible when its
// children are requested because empty InvalidateChldren() prevents its
@ -404,8 +404,8 @@ nsApplicationAccessible::CacheChildren()
}
nsAccessible*
nsApplicationAccessible::GetSiblingAtOffset(PRInt32 aOffset,
nsresult* aError) const
ApplicationAccessible::GetSiblingAtOffset(PRInt32 aOffset,
nsresult* aError) const
{
if (aError)
*aError = NS_OK; // fail peacefully
@ -417,7 +417,7 @@ nsApplicationAccessible::GetSiblingAtOffset(PRInt32 aOffset,
// nsIAccessible
NS_IMETHODIMP
nsApplicationAccessible::GetDOMNode(nsIDOMNode **aDOMNode)
ApplicationAccessible::GetDOMNode(nsIDOMNode** aDOMNode)
{
NS_ENSURE_ARG_POINTER(aDOMNode);
*aDOMNode = nsnull;
@ -425,7 +425,7 @@ nsApplicationAccessible::GetDOMNode(nsIDOMNode **aDOMNode)
}
NS_IMETHODIMP
nsApplicationAccessible::GetDocument(nsIAccessibleDocument **aDocument)
ApplicationAccessible::GetDocument(nsIAccessibleDocument** aDocument)
{
NS_ENSURE_ARG_POINTER(aDocument);
*aDocument = nsnull;
@ -433,7 +433,7 @@ nsApplicationAccessible::GetDocument(nsIAccessibleDocument **aDocument)
}
NS_IMETHODIMP
nsApplicationAccessible::GetRootDocument(nsIAccessibleDocument **aRootDocument)
ApplicationAccessible::GetRootDocument(nsIAccessibleDocument** aRootDocument)
{
NS_ENSURE_ARG_POINTER(aRootDocument);
*aRootDocument = nsnull;
@ -441,20 +441,20 @@ nsApplicationAccessible::GetRootDocument(nsIAccessibleDocument **aRootDocument)
}
NS_IMETHODIMP
nsApplicationAccessible::ScrollTo(PRUint32 aScrollType)
ApplicationAccessible::ScrollTo(PRUint32 aScrollType)
{
return NS_OK;
}
NS_IMETHODIMP
nsApplicationAccessible::ScrollToPoint(PRUint32 aCoordinateType,
PRInt32 aX, PRInt32 aY)
ApplicationAccessible::ScrollToPoint(PRUint32 aCoordinateType,
PRInt32 aX, PRInt32 aY)
{
return NS_OK;
}
NS_IMETHODIMP
nsApplicationAccessible::GetLanguage(nsAString &aLanguage)
ApplicationAccessible::GetLanguage(nsAString& aLanguage)
{
aLanguage.Truncate();
return NS_OK;

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

@ -40,8 +40,8 @@
*
* ***** END LICENSE BLOCK ***** */
#ifndef __NS_APPLICATION_ACCESSIBLE_H__
#define __NS_APPLICATION_ACCESSIBLE_H__
#ifndef MOZILLA_A11Y_APPLICATION_ACCESSIBLE_H__
#define MOZILLA_A11Y_APPLICATION_ACCESSIBLE_H__
#include "nsAccessibleWrap.h"
#include "nsIAccessibleApplication.h"
@ -50,21 +50,21 @@
#include "nsIXULAppInfo.h"
/**
* nsApplicationAccessible is for the whole application of Mozilla.
* Only one instance of nsApplicationAccessible exists for one Mozilla instance.
* ApplicationAccessible is for the whole application of Mozilla.
* Only one instance of ApplicationAccessible exists for one Mozilla instance.
* And this one should be created when Mozilla Startup (if accessibility
* feature has been enabled) and destroyed when Mozilla Shutdown.
*
* All the accessibility objects for toplevel windows are direct children of
* the nsApplicationAccessible instance.
* the ApplicationAccessible instance.
*/
class nsApplicationAccessible: public nsAccessibleWrap,
public nsIAccessibleApplication
class ApplicationAccessible: public nsAccessibleWrap,
public nsIAccessibleApplication
{
public:
nsApplicationAccessible();
ApplicationAccessible();
// nsISupports
NS_DECL_ISUPPORTS_INHERITED

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

@ -15,6 +15,7 @@ LIBXUL_LIBRARY = 1
CPPSRCS = \
ApplicationAccessible.cpp \
ARIAGridAccessible.cpp \
FormControlAccessible.cpp \
OuterDocAccessible.cpp \

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

@ -38,12 +38,12 @@
*
* ***** END LICENSE BLOCK ***** */
#ifndef __NS_APPLICATION_ACCESSIBLE_WRAP_H__
#define __NS_APPLICATION_ACCESSIBLE_WRAP_H__
#ifndef MOZILLA_A11Y_APPLICATION_ACCESSIBLE_WRAP_H__
#define MOZILLA_A11Y_APPLICATION_ACCESSIBLE_WRAP_H__
#include "nsApplicationAccessible.h"
#include "ApplicationAccessible.h"
class nsApplicationAccessibleWrap: public nsApplicationAccessible
class ApplicationAccessibleWrap: public ApplicationAccessible
{
public:
static void PreCreate() {}

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

@ -62,6 +62,7 @@ CMMSRCS = nsAccessNodeWrap.mm \
EXPORTS = \
ApplicationAccessibleWrap.h \
ARIAGridAccessibleWrap.h \
nsAccessNodeWrap.h \
nsTextAccessibleWrap.h \
@ -74,7 +75,6 @@ EXPORTS = \
nsHyperTextAccessibleWrap.h \
nsHTMLImageAccessibleWrap.h \
nsHTMLTableAccessibleWrap.h \
nsApplicationAccessibleWrap.h \
mozDocAccessible.h \
mozAccessible.h \
mozAccessibleProtocol.h \

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

@ -38,7 +38,7 @@
*
* ***** END LICENSE BLOCK ***** */
#include "nsApplicationAccessibleWrap.h"
#include "ApplicationAccessibleWrap.h"
#include "AccessibleApplication_i.c"
@ -48,11 +48,11 @@
////////////////////////////////////////////////////////////////////////////////
// nsISupports
NS_IMPL_ISUPPORTS_INHERITED0(nsApplicationAccessibleWrap,
nsApplicationAccessible)
NS_IMPL_ISUPPORTS_INHERITED0(ApplicationAccessibleWrap,
ApplicationAccessible)
NS_IMETHODIMP
nsApplicationAccessibleWrap::GetAttributes(nsIPersistentProperties** aAttributes)
ApplicationAccessibleWrap::GetAttributes(nsIPersistentProperties** aAttributes)
{
NS_ENSURE_ARG_POINTER(aAttributes);
*aAttributes = nsnull;
@ -80,7 +80,7 @@ nsApplicationAccessibleWrap::GetAttributes(nsIPersistentProperties** aAttributes
// IUnknown
STDMETHODIMP
nsApplicationAccessibleWrap::QueryInterface(REFIID iid, void** ppv)
ApplicationAccessibleWrap::QueryInterface(REFIID iid, void** ppv)
{
*ppv = NULL;
@ -97,7 +97,7 @@ nsApplicationAccessibleWrap::QueryInterface(REFIID iid, void** ppv)
// IAccessibleApplication
STDMETHODIMP
nsApplicationAccessibleWrap::get_appName(BSTR *aName)
ApplicationAccessibleWrap::get_appName(BSTR* aName)
{
__try {
*aName = NULL;
@ -121,7 +121,7 @@ __try {
}
STDMETHODIMP
nsApplicationAccessibleWrap::get_appVersion(BSTR *aVersion)
ApplicationAccessibleWrap::get_appVersion(BSTR* aVersion)
{
__try {
*aVersion = NULL;
@ -145,7 +145,7 @@ __try {
}
STDMETHODIMP
nsApplicationAccessibleWrap::get_toolkitName(BSTR *aName)
ApplicationAccessibleWrap::get_toolkitName(BSTR* aName)
{
__try {
if (IsDefunct())
@ -167,7 +167,7 @@ __try {
}
STDMETHODIMP
nsApplicationAccessibleWrap::get_toolkitVersion(BSTR *aVersion)
ApplicationAccessibleWrap::get_toolkitVersion(BSTR* aVersion)
{
__try {
*aVersion = NULL;
@ -191,15 +191,15 @@ __try {
}
////////////////////////////////////////////////////////////////////////////////
// nsApplicationAccessibleWrap public static
// ApplicationAccessibleWrap public static
void
nsApplicationAccessibleWrap::PreCreate()
ApplicationAccessibleWrap::PreCreate()
{
}
void
nsApplicationAccessibleWrap::Unload()
ApplicationAccessibleWrap::Unload()
{
}

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

@ -38,15 +38,15 @@
*
* ***** END LICENSE BLOCK ***** */
#ifndef __NS_APPLICATION_ACCESSIBLE_WRAP_H__
#define __NS_APPLICATION_ACCESSIBLE_WRAP_H__
#ifndef MOZILLA_A11Y_APPLICATION_ACCESSIBLE_WRAP_H__
#define MOZILLA_A11Y_APPLICATION_ACCESSIBLE_WRAP_H__
#include "nsApplicationAccessible.h"
#include "ApplicationAccessible.h"
#include "AccessibleApplication.h"
class nsApplicationAccessibleWrap: public nsApplicationAccessible,
public IAccessibleApplication
class ApplicationAccessibleWrap: public ApplicationAccessible,
public IAccessibleApplication
{
public:
// nsISupporst

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

@ -48,12 +48,13 @@ LIBXUL_LIBRARY = 1
CPPSRCS = \
ApplicationAccessibleWrap.cpp \
ARIAGridAccessibleWrap.cpp \
nsAccessNodeWrap.cpp \
nsAccessibleWrap.cpp \
nsTextAccessibleWrap.cpp \
nsDocAccessibleWrap.cpp \
nsHTMLWin32ObjectAccessible.cpp \
ARIAGridAccessibleWrap.cpp \
nsRootAccessibleWrap.cpp \
nsXULMenuAccessibleWrap.cpp \
nsXULListboxAccessibleWrap.cpp \
@ -61,7 +62,6 @@ CPPSRCS = \
nsHyperTextAccessibleWrap.cpp \
nsHTMLImageAccessibleWrap.cpp \
nsHTMLTableAccessibleWrap.cpp \
nsApplicationAccessibleWrap.cpp \
nsWinUtils.cpp \
ia2AccessibleAction.cpp \
ia2AccessibleComponent.cpp \
@ -78,6 +78,7 @@ CPPSRCS = \
$(NULL)
EXPORTS = \
ApplicationAccessibleWrap.h \
ARIAGridAccessibleWrap.h \
nsAccessNodeWrap.h \
nsAccessibleWrap.h \
@ -91,7 +92,6 @@ EXPORTS = \
nsHyperTextAccessibleWrap.h \
nsHTMLImageAccessibleWrap.h \
nsHTMLTableAccessibleWrap.h \
nsApplicationAccessibleWrap.h \
ia2AccessibleAction.h \
ia2AccessibleComponent.h \
CAccessibleImage.h \

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

@ -39,11 +39,11 @@
#include "nsAccessNodeWrap.h"
#include "AccessibleApplication.h"
#include "ApplicationAccessibleWrap.h"
#include "ISimpleDOMNode_i.c"
#include "Compatibility.h"
#include "nsAccessibilityService.h"
#include "nsApplicationAccessibleWrap.h"
#include "nsCoreUtils.h"
#include "nsRootAccessible.h"
#include "nsWinUtils.h"
@ -174,7 +174,7 @@ nsAccessNodeWrap::QueryService(REFGUID guidService, REFIID iid, void** ppv)
// Can get to IAccessibleApplication from any node via QS
if (iid == IID_IAccessibleApplication) {
nsApplicationAccessible *applicationAcc = GetApplicationAccessible();
ApplicationAccessible* applicationAcc = GetApplicationAccessible();
if (!applicationAcc)
return E_NOINTERFACE;

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

@ -38,12 +38,12 @@
*
* ***** END LICENSE BLOCK ***** */
#ifndef __NS_APPLICATION_ACCESSIBLE_WRAP_H__
#define __NS_APPLICATION_ACCESSIBLE_WRAP_H__
#ifndef MOZILLA_A11Y_APPLICATION_ACCESSIBLE_WRAP_H__
#define MOZILLA_A11Y_APPLICATION_ACCESSIBLE_WRAP_H__
#include "nsApplicationAccessible.h"
#include "ApplicationAccessible.h"
class nsApplicationAccessibleWrap: public nsApplicationAccessible
class ApplicationAccessibleWrap: public ApplicationAccessible
{
public:
static void PreCreate() {}

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

@ -54,6 +54,7 @@ CPPSRCS = \
$(NULL)
EXPORTS = \
ApplicationAccessibleWrap.h \
ARIAGridAccessibleWrap.h \
nsAccessNodeWrap.h \
nsTextAccessibleWrap.h \
@ -66,7 +67,6 @@ EXPORTS = \
nsHyperTextAccessibleWrap.h \
nsHTMLImageAccessibleWrap.h \
nsHTMLTableAccessibleWrap.h \
nsApplicationAccessibleWrap.h \
$(NULL)
# we don't want the shared lib, but we want to force the creation of a static lib.

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

@ -64,8 +64,7 @@
this.preinvoke = function rootContentRemoved_preinvoke()
{
// Set up target for hide event before we invoke.
var text =
getAccessible(getAccessible(getDocNode(aID)).firstChild).DOMNode;
var text = getAccessible(getAccessible(getDocNode(aID)).firstChild);
this.eventSeq[0].target = text;
}
@ -304,16 +303,21 @@
function insertElmUnderDocElmWhileBodyMissed(aID)
{
this.docNode = getDocNode(aID);
this.inputNode = getDocNode(aID).createElement("input");
this.docNode = null;
this.inputNode = null;
function getInputNode()
{ return this.inputNode; }
this.eventSeq = [
new invokerChecker(EVENT_SHOW, this.inputNode),
new invokerChecker(EVENT_REORDER, this.docNode)
new invokerChecker(EVENT_SHOW, getInputNode.bind(this)),
new invokerChecker(EVENT_REORDER, getDocNode, aID)
];
this.invoke = function invoke()
{
this.docNode = getDocNode(aID);
this.inputNode = this.docNode.createElement("input");
this.docNode.documentElement.appendChild(this.inputNode);
}
@ -389,6 +393,7 @@
// Test
//gA11yEventDumpID = "eventdump"; // debug stuff
//gA11yEventDumpToConsole = true;
var gQueue = null;

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

@ -425,9 +425,10 @@ pref("browser.link.open_newwindow", 3);
// 2: don't divert window.open with features
pref("browser.link.open_newwindow.restriction", 0);
// Enable browser frame
// Enable browser frames, but not OOP.
pref("dom.mozBrowserFramesEnabled", true);
pref("dom.mozBrowserFramesWhitelist", "http://homescreen.gaiamobile.org,http://browser.gaiamobile.org");
pref("dom.ipc.tabs.disabled", true);
// Temporary permission hack for WebSMS
pref("dom.sms.enabled", true);

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

@ -524,6 +524,25 @@
phase="capturing"
modifiers="accel"
action="this.selectEngine(event, (event.detail > 0));"/>
<handler event="focus">
<![CDATA[
// Speculatively connect to the current engine's search URI (and
// suggest URI, if different) to reduce request latency
const SUGGEST_TYPE = "application/x-suggestions+json";
var engine = this.currentEngine;
var connector =
Services.io.QueryInterface(Components.interfaces.nsISpeculativeConnect);
var searchURI = engine.getSubmission("dummy").uri;
connector.speculativeConnect(searchURI, null, null);
if (engine.supportsResponseType(SUGGEST_TYPE)) {
var suggestURI = engine.getSubmission("dummy", SUGGEST_TYPE).uri;
if (suggestURI.prePath != searchURI.prePath)
connector.speculativeConnect(suggestURI, null, null);
}
]]></handler>
</handlers>
</binding>

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

@ -18,11 +18,11 @@ function test() {
let browser = tab.linkedBrowser;
whenBrowserLoaded(browser, function () {
ss.setTabState(tab, JSON.stringify(tabState));
waitForTabState(tab, tabState, function () {
let sessionHistory = browser.sessionHistory;
let entry = sessionHistory.getEntryAtIndex(0, false);
entry.QueryInterface(Ci.nsISHContainer);
whenChildCount(entry, 1, function () {
whenChildCount(entry, 2, function () {
@ -49,13 +49,6 @@ function test() {
});
}
function whenBrowserLoaded(aBrowser, aCallback) {
aBrowser.addEventListener("load", function onLoad() {
aBrowser.removeEventListener("load", onLoad, true);
executeSoon(aCallback);
}, true);
}
function whenChildCount(aEntry, aChildCount, aCallback) {
if (aEntry.childCount == aChildCount)
aCallback();

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

@ -18,11 +18,11 @@ function test() {
let browser = tab.linkedBrowser;
whenBrowserLoaded(browser, function () {
ss.setTabState(tab, JSON.stringify(tabState));
waitForTabState(tab, tabState, function() {
let sessionHistory = browser.sessionHistory;
let entry = sessionHistory.getEntryAtIndex(0, false);
entry.QueryInterface(Ci.nsISHContainer);
whenChildCount(entry, 1, function () {
whenChildCount(entry, 2, function () {
@ -50,13 +50,6 @@ function test() {
});
}
function whenBrowserLoaded(aBrowser, aCallback) {
aBrowser.addEventListener("load", function onLoad() {
aBrowser.removeEventListener("load", onLoad, true);
executeSoon(aCallback);
}, true);
}
function whenChildCount(aEntry, aChildCount, aCallback) {
if (aEntry.childCount == aChildCount)
aCallback();

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

@ -45,6 +45,10 @@ registerCleanupFunction(function () {
Services.prefs.clearUserPref("browser.sessionstore.restore_on_demand");
});
// This kicks off the search service used on about:home and allows the
// session restore tests to be run standalone without triggering errors.
Cc["@mozilla.org/browser/clh;1"].getService(Ci.nsIBrowserHandler).defaultArgs;
// This assumes that tests will at least have some state/entries
function waitForBrowserState(aState, aSetStateCallback) {
let windows = [window];
@ -128,6 +132,27 @@ function waitForBrowserState(aState, aSetStateCallback) {
ss.setBrowserState(JSON.stringify(aState));
}
// Doesn't assume that the tab needs to be closed in a cleanup function.
// If that's the case, the test author should handle that in the test.
function waitForTabState(aTab, aState, aCallback) {
let listening = true;
function onSSTabRestored() {
aTab.removeEventListener("SSTabRestored", onSSTabRestored, false);
listening = false;
aCallback();
}
aTab.addEventListener("SSTabRestored", onSSTabRestored, false);
registerCleanupFunction(function() {
if (listening) {
aTab.removeEventListener("SSTabRestored", onSSTabRestored, false);
}
});
ss.setTabState(aTab, JSON.stringify(aState));
}
// waitForSaveState waits for a state write but not necessarily for the state to
// turn dirty.
function waitForSaveState(aSaveStateCallback) {
@ -166,6 +191,13 @@ function waitForSaveState(aSaveStateCallback) {
Services.obs.addObserver(observer, topic, false);
};
function whenBrowserLoaded(aBrowser, aCallback) {
aBrowser.addEventListener("load", function onLoad() {
aBrowser.removeEventListener("load", onLoad, true);
executeSoon(aCallback);
}, true);
}
var gUniqueCounter = 0;
function r() {
return Date.now() + "-" + (++gUniqueCounter);

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

@ -1,209 +0,0 @@
#!/usr/bin/env python
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
#
# The contents of this file are subject to the Mozilla Public License Version
# 1.1 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
# for the specific language governing rights and limitations under the
# License.
#
# The Original Code is Mozilla Corporation Code.
#
# The Initial Developer of the Original Code is
# Mikeal Rogers.
# Portions created by the Initial Developer are Copyright (C) 2008
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
# Mikeal Rogers <mikeal.rogers@gmail.com>
# Henrik Skupin <hskupin@mozilla.com>
# Clint Talbert <ctalbert@mozilla.com>
#
# Alternatively, the contents of this file may be used under the terms of
# either the GNU General Public License Version 2 or later (the "GPL"), or
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****
"""
file for interface to transform introspected system information to a format
pallatable to Mozilla
Information:
- os : what operating system ['win', 'mac', 'linux', ...]
- bits : 32 or 64
- processor : processor architecture ['x86', 'x86_64', 'ppc', ...]
- version : operating system version string
For windows, the service pack information is also included
"""
# TODO: it might be a good idea of adding a system name (e.g. 'Ubuntu' for
# linux) to the information; I certainly wouldn't want anyone parsing this
# information and having behaviour depend on it
import os
import platform
import re
import sys
# keep a copy of the os module since updating globals overrides this
_os = os
class unknown(object):
"""marker class for unknown information"""
def __nonzero__(self):
return False
def __str__(self):
return 'UNKNOWN'
unknown = unknown() # singleton
# get system information
info = {'os': unknown,
'processor': unknown,
'version': unknown,
'bits': unknown }
(system, node, release, version, machine, processor) = platform.uname()
(bits, linkage) = platform.architecture()
# get os information and related data
if system in ["Microsoft", "Windows"]:
info['os'] = 'win'
# There is a Python bug on Windows to determine platform values
# http://bugs.python.org/issue7860
if "PROCESSOR_ARCHITEW6432" in os.environ:
processor = os.environ.get("PROCESSOR_ARCHITEW6432", processor)
else:
processor = os.environ.get('PROCESSOR_ARCHITECTURE', processor)
system = os.environ.get("OS", system).replace('_', ' ')
service_pack = os.sys.getwindowsversion()[4]
info['service_pack'] = service_pack
elif system == "Linux":
(distro, version, codename) = platform.dist()
version = distro + " " + version
if not processor:
processor = machine
info['os'] = 'linux'
elif system == "Darwin":
(release, versioninfo, machine) = platform.mac_ver()
version = "OS X " + release
info['os'] = 'mac'
elif sys.platform in ('solaris', 'sunos5'):
info['os'] = 'unix'
version = sys.platform
info['version'] = version # os version
# processor type and bits
if processor in ["i386", "i686"]:
if bits == "32bit":
processor = "x86"
elif bits == "64bit":
processor = "x86_64"
elif processor == "AMD64":
bits = "64bit"
processor = "x86_64"
elif processor == "Power Macintosh":
processor = "ppc"
bits = re.search('(\d+)bit', bits).group(1)
info.update({'processor': processor,
'bits': int(bits),
})
# standard value of choices, for easy inspection
choices = {'os': ['linux', 'win', 'mac', 'unix'],
'bits': [32, 64],
'processor': ['x86', 'x86_64', 'ppc']}
def sanitize(info):
"""Do some sanitization of input values, primarily
to handle universal Mac builds."""
if "processor" in info and info["processor"] == "universal-x86-x86_64":
# If we're running on OS X 10.6 or newer, assume 64-bit
if release[:4] >= "10.6":
info["processor"] = "x86_64"
info["bits"] = 64
else:
info["processor"] = "x86"
info["bits"] = 32
# method for updating information
def update(new_info):
"""update the info"""
info.update(new_info)
sanitize(info)
globals().update(info)
# convenience data for os access
for os_name in choices['os']:
globals()['is' + os_name.title()] = info['os'] == os_name
# unix is special
if isLinux:
globals()['isUnix'] = True
update({})
# exports
__all__ = info.keys()
__all__ += ['is' + os_name.title() for os_name in choices['os']]
__all__ += ['info', 'unknown', 'main', 'choices', 'update']
def main(args=None):
# parse the command line
from optparse import OptionParser
parser = OptionParser()
for key in choices:
parser.add_option('--%s' % key, dest=key,
action='store_true', default=False,
help="display choices for %s" % key)
options, args = parser.parse_args()
# args are JSON blobs to override info
if args:
try:
from json import loads
except ImportError:
try:
from simplejson import loads
except ImportError:
def loads(string):
"""*really* simple json; will not work with unicode"""
return eval(string, {'true': True, 'false': False, 'null': None})
for arg in args:
if _os.path.exists(arg):
string = file(arg).read()
else:
string = arg
update(loads(string))
# print out choices if requested
flag = False
for key, value in options.__dict__.items():
if value is True:
print '%s choices: %s' % (key, ' '.join([str(choice)
for choice in choices[key]]))
flag = True
if flag: return
# otherwise, print out all info
for key, value in info.items():
print '%s: %s' % (key, value)
if __name__ == '__main__':
main()

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

@ -6327,44 +6327,6 @@ if test -n "$MOZ_TREE_FREETYPE"; then
AC_SUBST(CAIRO_FT_CFLAGS)
fi
dnl ========================================================
dnl Web App Runtime
dnl ========================================================
MOZ_ARG_DISABLE_BOOL(webapp-runtime,
[ --disable-webapp-runtime Disable Web App Runtime],
MOZ_WEBAPP_RUNTIME=,
MOZ_WEBAPP_RUNTIME=1)
if test -n "$MOZ_WEBAPP_RUNTIME" -a "$OS_ARCH" = "WINNT"; then
# Disable Web App Runtime for Windows builds that use the new toolkit if the
# required major version and minimum minor version of Unicode NSIS isn't in
# the path.
REQ_NSIS_MAJOR_VER=2
MIN_NSIS_MINOR_VER=33
MOZ_PATH_PROGS(MAKENSISU, $MAKENSISU makensisu-2.46 makensisu makensis)
if test -z "$MAKENSISU" -o "$MAKENSISU" = ":"; then
AC_MSG_ERROR([To build the Web App Runtime you must have the latest MozillaBuild or Unicode NSIS with a major version of $REQ_NSIS_MAJOR_VER and a minimum minor version of $MIN_NSIS_MINOR_VER in your path. To build without the Web App Runtime reconfigure using --disable-webapp-runtime.])
fi
changequote(,)
MAKENSISU_VER=`"$MAKENSISU" -version 2>/dev/null | sed -e '/-Unicode/!s/.*//g' -e 's/^v\([0-9]\+\.[0-9]\+\)\-Unicode$/\1/g'`
changequote([,])
if test ! "$MAKENSISU_VER" = ""; then
MAKENSISU_MAJOR_VER=`echo $MAKENSISU_VER | $AWK -F\. '{ print $1 }'`
MAKENSISU_MINOR_VER=`echo $MAKENSISU_VER | $AWK -F\. '{ print $2 }'`
fi
AC_MSG_CHECKING([for Unicode NSIS with major version == $REQ_NSIS_MAJOR_VER and minor version >= $MIN_NSIS_MINOR_VER])
if test "$MAKENSISU_VER" = "" ||
test ! "$MAKENSISU_MAJOR_VER" = "$REQ_NSIS_MAJOR_VER" -o \
! "$MAKENSISU_MINOR_VER" -ge $MIN_NSIS_MINOR_VER; then
AC_MSG_RESULT([no])
AC_MSG_ERROR([To build the Web App Runtime you must have the latest MozillaBuild or Unicode NSIS with a major version of $REQ_NSIS_MAJOR_VER and a minimum minor version of $MIN_NSIS_MINOR_VER in your path. To build without the Web App Runtime reconfigure using --disable-webapp-runtime.])
fi
AC_MSG_RESULT([yes])
fi
AC_SUBST(MOZ_WEBAPP_RUNTIME)
if test "$MOZ_WEBAPP_RUNTIME"; then
AC_DEFINE(MOZ_WEBAPP_RUNTIME)
fi
dnl ========================================================
dnl Installer
dnl ========================================================
@ -6403,6 +6365,21 @@ if test "$OS_ARCH" = "WINNT"; then
fi
fi
dnl ========================================================
dnl Web App Runtime
dnl ========================================================
MOZ_ARG_DISABLE_BOOL(webapp-runtime,
[ --disable-webapp-runtime Disable Web App Runtime],
MOZ_WEBAPP_RUNTIME=,
MOZ_WEBAPP_RUNTIME=1)
if test "$OS_ARCH" = "WINNT" -a -z "$MAKENSISU" -a -n "$CROSS_COMPILE"; then
MOZ_WEBAPP_RUNTIME=
fi
AC_SUBST(MOZ_WEBAPP_RUNTIME)
if test "$MOZ_WEBAPP_RUNTIME"; then
AC_DEFINE(MOZ_WEBAPP_RUNTIME)
fi
AC_MSG_CHECKING([for tar archiver])
AC_CHECK_PROGS(TAR, gnutar gtar tar, "")
if test -z "$TAR"; then

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

@ -457,8 +457,13 @@ nsFrameLoader::ReallyStartLoadingInternal()
}
}
// FIXME get error codes from child
mRemoteBrowser->LoadURL(mURIToLoad);
if (mRemoteBrowserShown || ShowRemoteFrame(nsIntSize(0, 0))) {
// FIXME get error codes from child
mRemoteBrowser->LoadURL(mURIToLoad);
} else {
NS_WARNING("[nsFrameLoader] ReallyStartLoadingInternal tried but couldn't show remote browser.\n");
}
return NS_OK;
}
@ -912,6 +917,18 @@ nsFrameLoader::ShowRemoteFrame(const nsIntSize& size)
// cross-process layers; need to figure out what behavior we really
// want here. For now, hack.
if (!mRemoteBrowserShown) {
if (!mOwnerContent ||
!mOwnerContent->GetCurrentDoc()) {
return false;
}
nsRefPtr<layers::LayerManager> layerManager =
nsContentUtils::LayerManagerForDocument(mOwnerContent->GetCurrentDoc());
if (!layerManager) {
// This is just not going to work.
return false;
}
mRemoteBrowser->Show(size);
mRemoteBrowserShown = true;
@ -1355,19 +1372,27 @@ nsFrameLoader::SetOwnerContent(Element* aContent)
}
}
bool
nsFrameLoader::OwnerIsBrowserFrame()
{
nsCOMPtr<nsIMozBrowserFrame> browserFrame = do_QueryInterface(mOwnerContent);
bool isBrowser = false;
if (browserFrame) {
browserFrame->GetReallyIsBrowser(&isBrowser);
}
return isBrowser;
}
bool
nsFrameLoader::ShouldUseRemoteProcess()
{
// Check for *disabled* multi-process first: environment, pref
// Then check for *enabled* multi-process attribute
// Default is not-remote.
if (PR_GetEnv("MOZ_DISABLE_OOP_TABS") ||
Preferences::GetBool("dom.ipc.tabs.disabled", false)) {
return false;
}
return (bool) mOwnerContent->AttrValueIs(kNameSpaceID_None,
return OwnerIsBrowserFrame() ||
(bool) mOwnerContent->AttrValueIs(kNameSpaceID_None,
nsGkAtoms::Remote,
nsGkAtoms::_true,
eCaseMatters);
@ -1842,24 +1867,27 @@ nsFrameLoader::TryRemoteBrowser()
nsCOMPtr<nsIDocShellTreeItem> parentAsItem(do_QueryInterface(parentAsWebNav));
PRInt32 parentType;
parentAsItem->GetItemType(&parentType);
// <iframe mozbrowser> gets to skip these checks.
if (!OwnerIsBrowserFrame()) {
PRInt32 parentType;
parentAsItem->GetItemType(&parentType);
if (parentType != nsIDocShellTreeItem::typeChrome) {
return false;
}
if (parentType != nsIDocShellTreeItem::typeChrome) {
return false;
}
if (!mOwnerContent->IsXUL()) {
return false;
}
if (!mOwnerContent->IsXUL()) {
return false;
}
nsAutoString value;
mOwnerContent->GetAttr(kNameSpaceID_None, nsGkAtoms::type, value);
nsAutoString value;
mOwnerContent->GetAttr(kNameSpaceID_None, nsGkAtoms::type, value);
if (!value.LowerCaseEqualsLiteral("content") &&
!StringBeginsWith(value, NS_LITERAL_STRING("content-"),
nsCaseInsensitiveStringComparator())) {
return false;
if (!value.LowerCaseEqualsLiteral("content") &&
!StringBeginsWith(value, NS_LITERAL_STRING("content-"),
nsCaseInsensitiveStringComparator())) {
return false;
}
}
PRUint32 chromeFlags = 0;
@ -2131,6 +2159,19 @@ nsFrameLoader::GetRootContentView(nsIContentView** aContentView)
return NS_OK;
}
static already_AddRefed<nsIDocShell>
GetRootDocShell(nsIDocument *aDocument)
{
nsCOMPtr<nsIWebNavigation> webNav = do_GetInterface(aDocument->GetWindow());
nsCOMPtr<nsIDocShellTreeItem> treeItem = do_QueryInterface(webNav);
NS_ENSURE_TRUE(treeItem, NULL);
nsCOMPtr<nsIDocShellTreeItem> rootItem;
treeItem->GetRootTreeItem(getter_AddRefs(rootItem));
nsCOMPtr<nsIDocShell> rootDocShell = do_QueryInterface(rootItem);
return rootDocShell.forget();
}
nsresult
nsFrameLoader::EnsureMessageManager()
{
@ -2159,8 +2200,12 @@ nsFrameLoader::EnsureMessageManager()
NS_ENSURE_STATE(cx);
nsCOMPtr<nsIDOMChromeWindow> chromeWindow =
do_QueryInterface(mOwnerContent->OwnerDoc()->GetWindow());
NS_ENSURE_STATE(chromeWindow);
do_QueryInterface(OwnerDoc()->GetWindow());
if (!chromeWindow) {
nsCOMPtr<nsIDocShell> rootDocShell = GetRootDocShell(OwnerDoc());
nsCOMPtr<nsIDOMWindow> rootWindow = do_GetInterface(rootDocShell);
chromeWindow = do_GetInterface(rootWindow);
}
nsCOMPtr<nsIChromeFrameMessageManager> parentManager;
chromeWindow->GetMessageManager(getter_AddRefs(parentManager));

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

@ -295,6 +295,12 @@ private:
bool ShouldUseRemoteProcess();
/**
* Is this a frameloader for a bona fide <iframe mozbrowser>? (I.e., does
* the frame return true for nsIMozBrowserFrame::GetReallyIsBrowser()?)
*/
bool OwnerIsBrowserFrame();
/**
* If we are an IPC frame, set mRemoteFrame. Otherwise, create and
* initialize mDocShell.

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

@ -83,9 +83,6 @@ nsresult NS_NewContentSubtreeIterator(nsIContentIterator** aInstancePtrResult);
if (!nsContentUtils::CanCallerAccess(node_)) { \
return NS_ERROR_DOM_SECURITY_ERR; \
} \
if (mIsDetached) { \
return NS_ERROR_DOM_INVALID_STATE_ERR; \
} \
PR_END_MACRO
static void InvalidateAllFrames(nsINode* aNode)
@ -653,9 +650,6 @@ nsRange::IsPointInRange(nsIDOMNode* aParent, PRInt32 aOffset, bool* aResult)
NS_IMETHODIMP
nsRange::ComparePoint(nsIDOMNode* aParent, PRInt32 aOffset, PRInt16* aResult)
{
if (mIsDetached)
return NS_ERROR_DOM_INVALID_STATE_ERR;
// our range is in a good state?
if (!mIsPositioned)
return NS_ERROR_NOT_INITIALIZED;
@ -755,8 +749,7 @@ nsRange::DoSetRange(nsINode* aStartN, PRInt32 aStartOffset,
if (newCommonAncestor) {
RegisterCommonAncestor(newCommonAncestor);
} else {
NS_ASSERTION(mIsDetached || !mIsPositioned,
"unexpected disconnected nodes");
NS_ASSERTION(!mIsPositioned, "unexpected disconnected nodes");
mInSelection = false;
}
}
@ -844,8 +837,6 @@ nsRange::GetEndOffset(PRInt32* aEndOffset)
NS_IMETHODIMP
nsRange::GetCollapsed(bool* aIsCollapsed)
{
if(mIsDetached)
return NS_ERROR_DOM_INVALID_STATE_ERR;
if (!mIsPositioned)
return NS_ERROR_NOT_INITIALIZED;
@ -858,8 +849,6 @@ NS_IMETHODIMP
nsRange::GetCommonAncestorContainer(nsIDOMNode** aCommonParent)
{
*aCommonParent = nsnull;
if(mIsDetached)
return NS_ERROR_DOM_INVALID_STATE_ERR;
if (!mIsPositioned)
return NS_ERROR_NOT_INITIALIZED;
@ -1049,8 +1038,6 @@ nsRange::SetEndAfter(nsIDOMNode* aSibling)
NS_IMETHODIMP
nsRange::Collapse(bool aToStart)
{
if(mIsDetached)
return NS_ERROR_DOM_INVALID_STATE_ERR;
if (!mIsPositioned)
return NS_ERROR_NOT_INITIALIZED;
@ -1502,9 +1489,6 @@ nsresult nsRange::CutContents(nsIDOMDocumentFragment** aFragment)
*aFragment = nsnull;
}
if (IsDetached())
return NS_ERROR_DOM_INVALID_STATE_ERR;
nsresult rv;
nsCOMPtr<nsIDocument> doc = mStartParent->OwnerDoc();
@ -1782,8 +1766,6 @@ nsRange::CompareBoundaryPoints(PRUint16 aHow, nsIDOMRange* aOtherRange,
nsRange* otherRange = static_cast<nsRange*>(aOtherRange);
NS_ENSURE_TRUE(otherRange, NS_ERROR_NULL_POINTER);
if(mIsDetached || otherRange->IsDetached())
return NS_ERROR_DOM_INVALID_STATE_ERR;
if (!mIsPositioned || !otherRange->IsPositioned())
return NS_ERROR_NOT_INITIALIZED;
@ -1883,9 +1865,6 @@ nsRange::CloneParentsBetween(nsIDOMNode *aAncestor,
NS_IMETHODIMP
nsRange::CloneContents(nsIDOMDocumentFragment** aReturn)
{
if (IsDetached())
return NS_ERROR_DOM_INVALID_STATE_ERR;
nsresult res;
nsCOMPtr<nsIDOMNode> commonAncestor;
res = GetCommonAncestorContainer(getter_AddRefs(commonAncestor));
@ -2078,9 +2057,6 @@ nsRange::CloneContents(nsIDOMDocumentFragment** aReturn)
nsresult
nsRange::CloneRange(nsRange** aReturn) const
{
if(mIsDetached)
return NS_ERROR_DOM_INVALID_STATE_ERR;
if (aReturn == 0)
return NS_ERROR_NULL_POINTER;
@ -2264,9 +2240,6 @@ nsRange::SurroundContents(nsIDOMNode* aNewParent)
NS_IMETHODIMP
nsRange::ToString(nsAString& aReturn)
{
if(mIsDetached)
return NS_ERROR_DOM_INVALID_STATE_ERR;
// clear the string
aReturn.Truncate();
@ -2358,17 +2331,8 @@ nsRange::ToString(nsAString& aReturn)
NS_IMETHODIMP
nsRange::Detach()
{
if(mIsDetached)
return NS_ERROR_DOM_INVALID_STATE_ERR;
if (IsInSelection()) {
::InvalidateAllFrames(GetRegisteredCommonAncestor());
}
// No-op, but still set mIsDetached for telemetry (bug 702948)
mIsDetached = true;
DoSetRange(nsnull, 0, nsnull, 0, nsnull);
return NS_OK;
}

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

@ -108,11 +108,6 @@ public:
return mIsPositioned;
}
bool IsDetached() const
{
return mIsDetached;
}
bool Collapsed() const
{
return mIsPositioned && mStartParent == mEndParent &&
@ -138,7 +133,7 @@ public:
*/
void SetInSelection(bool aInSelection)
{
if (mInSelection == aInSelection || mIsDetached) {
if (mInSelection == aInSelection) {
return;
}
mInSelection = aInSelection;
@ -245,7 +240,6 @@ protected:
return;
}
mIsNested = true;
NS_ASSERTION(!mRange->IsDetached(), "detached range in selection");
mCommonAncestor = mRange->GetRegisteredCommonAncestor();
}
~AutoInvalidateSelection();

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

@ -100,6 +100,8 @@
#include "nsIDOMUIEvent.h"
#include "nsDOMDragEvent.h"
#include "nsIDOMNSEditableElement.h"
#include "nsIDOMMozBrowserFrame.h"
#include "nsIMozBrowserFrame.h"
#include "nsCaret.h"
@ -1701,12 +1703,30 @@ nsEventStateManager::DispatchCrossProcessEvent(nsEvent* aEvent, nsIFrameLoader*
bool
nsEventStateManager::IsRemoteTarget(nsIContent* target) {
return target &&
(target->Tag() == nsGkAtoms::browser ||
target->Tag() == nsGkAtoms::iframe) &&
target->IsXUL() &&
target->AttrValueIs(kNameSpaceID_None, nsGkAtoms::Remote,
nsGkAtoms::_true, eIgnoreCase);
if (!target) {
return false;
}
// <browser/iframe remote=true> from XUL
if ((target->Tag() == nsGkAtoms::browser ||
target->Tag() == nsGkAtoms::iframe) &&
target->IsXUL() &&
target->AttrValueIs(kNameSpaceID_None, nsGkAtoms::Remote,
nsGkAtoms::_true, eIgnoreCase)) {
return true;
}
// <frame/iframe mozbrowser>
nsCOMPtr<nsIMozBrowserFrame> browserFrame = do_QueryInterface(target);
if (browserFrame) {
bool isRemote = false;
browserFrame->GetReallyIsBrowser(&isRemote);
if (isRemote) {
return true;
}
}
return false;
}

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

@ -369,33 +369,6 @@ function run_extract_test() {
// Clean up after ourselves.
walker = null;
/* Whenever a DOM range is detached, we cannot use any methods on
it - including extracting its contents or deleting its contents. It
should throw a NS_ERROR_DOM_INVALID_STATE_ERR exception.
*/
dump("Detached range test\n");
var compareFrag = getFragment(baseSource);
baseFrag = getFragment(baseSource);
baseRange = getRange(baseSource, baseFrag);
baseRange.detach();
try {
var cutFragment = baseRange.extractContents();
do_throw("Should have thrown INVALID_STATE_ERR!");
} catch (e if (e instanceof C_i.nsIException &&
e.result == INVALID_STATE_ERR)) {
// do nothing
}
do_check_true(compareFrag.isEqualNode(baseFrag));
try {
baseRange.deleteContents();
do_throw("Should have thrown INVALID_STATE_ERR!");
} catch (e if (e instanceof C_i.nsIException &&
e.result == INVALID_STATE_ERR)) {
// do nothing
}
do_check_true(compareFrag.isEqualNode(baseFrag));
}
}

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

@ -2762,6 +2762,11 @@ nsXULDocument::LoadOverlayInternal(nsIURI* aURI, bool aIsDynamic,
// Not there. Initiate a load.
PR_LOG(gXULLog, PR_LOG_DEBUG, ("xul: overlay was not cached"));
if (mIsGoingAway) {
PR_LOG(gXULLog, PR_LOG_DEBUG, ("xul: ...and document already destroyed"));
return NS_ERROR_NOT_AVAILABLE;
}
// We'll set the right principal on the proto doc when we get
// OnStartRequest from the parser, so just pass in a null principal for
// now.

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

@ -7505,18 +7505,34 @@ nsDocShell::CreateContentViewer(const char *aContentType,
mLoadType = mFailedLoadType;
nsCOMPtr<nsIChannel> failedChannel = mFailedChannel;
nsCOMPtr<nsIURI> failedURI = mFailedURI;
// Make sure we have a URI to set currentURI.
nsCOMPtr<nsIURI> failedURI;
if (failedChannel) {
NS_GetFinalChannelURI(failedChannel, getter_AddRefs(failedURI));
}
if (!failedURI) {
failedURI = mFailedURI;
}
// When we don't have failedURI, something wrong will happen. See
// bug 291876.
MOZ_ASSERT(failedURI, "We don't have a URI for history APIs.");
mFailedChannel = nsnull;
mFailedURI = nsnull;
// Create an shistory entry for the old load, if we have a channel
if (failedChannel) {
mURIResultedInDocument = true;
OnLoadingSite(failedChannel, true, false);
} else if (failedURI) {
mURIResultedInDocument = true;
OnNewURI(failedURI, nsnull, nsnull, mLoadType, true, false,
// Create an shistory entry for the old load.
if (failedURI) {
#ifdef DEBUG
bool errorOnLocationChangeNeeded =
#endif
OnNewURI(failedURI, failedChannel, nsnull, mLoadType, true, false,
false);
MOZ_ASSERT(!errorOnLocationChangeNeeded,
"We have to fire onLocationChange again.");
}
// Be sure to have a correct mLSHE, it may have been cleared by
@ -7533,9 +7549,6 @@ nsDocShell::CreateContentViewer(const char *aContentType,
mLSHE = do_QueryInterface(entry);
}
// Set our current URI
SetCurrentURI(failedURI);
mLoadType = LOAD_ERROR_PAGE;
}

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

@ -79,11 +79,6 @@ function step1A() {
}
function step1B(aWebProgress, aRequest, aLocation, aFlags) {
/* XXX Here we receive 2 notifications, due to bug 673752. */
if (!aRequest) {
return;
}
is(aLocation.spec, kDNSErrorURI, "Error page's URI (1)");
ok(!(aFlags & Components.interfaces.nsIWebProgressListener
@ -161,9 +156,6 @@ function step4A() {
}
function step4B(aWebProgress, aRequest, aLocation, aFlags) {
if (!aRequest) // See step1B(...) and bug 673752.
return;
is(aLocation.spec, kDNSErrorURI, "Go back to the error URI (4)");
ok(!(aFlags & Components.interfaces.nsIWebProgressListener

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

@ -177,7 +177,7 @@ NSResultToNameAndMessage(nsresult aNSResult,
nsresult
NS_GetNameAndMessageForDOMNSResult(nsresult aNSResult, const char** aName,
const char** aMessage)
const char** aMessage, PRUint16* aCode)
{
const char* name = nsnull;
const char* message = nsnull;
@ -187,6 +187,9 @@ NS_GetNameAndMessageForDOMNSResult(nsresult aNSResult, const char** aName,
if (name && message) {
*aName = name;
*aMessage = message;
if (aCode) {
*aCode = code;
}
return NS_OK;
}

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

@ -64,7 +64,8 @@ protected:
nsresult
NS_GetNameAndMessageForDOMNSResult(nsresult aNSResult, const char** aName,
const char** aMessage);
const char** aMessage,
PRUint16* aCode = nsnull);
#define DECL_INTERNAL_DOM_EXCEPTION(domname) \
nsresult \

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

@ -8,6 +8,7 @@
#define mozilla_dom_bindings_Utils_h__
#include "mozilla/dom/bindings/DOMJSClass.h"
#include "mozilla/dom/workers/Workers.h"
#include "jsapi.h"
#include "jsfriendapi.h"
@ -25,12 +26,14 @@ template<bool mainThread>
inline bool
Throw(JSContext* cx, nsresult rv)
{
using mozilla::dom::workers::exceptions::ThrowDOMExceptionForNSResult;
// XXX Introduce exception machinery.
if (mainThread) {
XPCThrower::Throw(rv, cx);
} else {
if (!JS_IsExceptionPending(cx)) {
JS_ReportError(cx, "Exception thrown (nsresult = %x).", rv);
ThrowDOMExceptionForNSResult(cx, rv);
}
}
return false;

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

@ -233,9 +233,9 @@ ConsoleListener::Observe(nsIConsoleMessage* aMessage)
ContentChild* ContentChild::sSingleton;
ContentChild::ContentChild()
: mID(PRUint64(-1))
#ifdef ANDROID
: mScreenSize(0, 0)
, mID(PRUint64(-1))
, mScreenSize(0, 0)
#endif
{
// This process is a content process, so it's clearly running in

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

@ -201,8 +201,6 @@ private:
gfxIntSize mScreenSize;
#endif
AppInfo mAppInfo;
/**
* An ID unique to the process containing our corresponding
* content parent.
@ -212,6 +210,8 @@ private:
*/
PRUint64 mID;
AppInfo mAppInfo;
static ContentChild* sSingleton;
DISALLOW_EVIL_CONSTRUCTORS(ContentChild);

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

@ -70,6 +70,7 @@
#include "nsIViewManager.h"
#include "mozilla/unused.h"
#include "nsDebug.h"
#include "nsPrintfCString.h"
using namespace mozilla::dom;
using namespace mozilla::ipc;
@ -93,6 +94,7 @@ TabParent::TabParent()
, mIMESeqno(0)
, mDPI(0)
, mActive(false)
, mShown(false)
{
}
@ -104,13 +106,7 @@ void
TabParent::SetOwnerElement(nsIDOMElement* aElement)
{
mFrameElement = aElement;
// Cache the DPI of the screen, since we may lose the element/widget later
if (aElement) {
nsCOMPtr<nsIWidget> widget = GetWidget();
NS_ABORT_IF_FALSE(widget, "Non-null OwnerElement must provide a widget!");
mDPI = widget->GetDPI();
}
TryCacheDPI();
}
void
@ -197,6 +193,16 @@ TabParent::AnswerCreateWindow(PBrowserParent** retval)
void
TabParent::LoadURL(nsIURI* aURI)
{
if (!mShown) {
nsCAutoString spec;
if (aURI) {
aURI->GetSpec(spec);
}
NS_WARNING(nsPrintfCString("TabParent::LoadURL(%s) called before "
"Show(). Ignoring LoadURL.\n", spec.get()).get());
return;
}
nsCString spec;
aURI->GetSpec(spec);
@ -207,6 +213,7 @@ void
TabParent::Show(const nsIntSize& size)
{
// sigh
mShown = true;
unused << SendShow(size);
}
@ -621,6 +628,7 @@ TabParent::RecvSetInputContext(const PRInt32& aIMEEnabled,
bool
TabParent::RecvGetDPI(float* aValue)
{
TryCacheDPI();
NS_ABORT_IF_FALSE(mDPI > 0,
"Must not ask for DPI before OwnerElement is received!");
*aValue = mDPI;
@ -848,6 +856,19 @@ TabParent::GetFrameLoader() const
return frameLoaderOwner ? frameLoaderOwner->GetFrameLoader() : nsnull;
}
void
TabParent::TryCacheDPI()
{
if (mDPI > 0) {
return;
}
nsCOMPtr<nsIWidget> widget = GetWidget();
if (widget) {
mDPI = widget->GetDPI();
}
}
already_AddRefed<nsIWidget>
TabParent::GetWidget() const
{
@ -859,7 +880,8 @@ TabParent::GetWidget() const
if (!frame)
return nsnull;
return nsCOMPtr<nsIWidget>(frame->GetNearestWidget()).forget();
nsCOMPtr<nsIWidget> widget = frame->GetNearestWidget();
return widget.forget();
}
} // namespace tabs

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

@ -233,10 +233,12 @@ protected:
float mDPI;
bool mActive;
bool mShown;
private:
already_AddRefed<nsFrameLoader> GetFrameLoader() const;
already_AddRefed<nsIWidget> GetWidget() const;
void TryCacheDPI();
};
} // namespace dom

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

@ -314,8 +314,7 @@ typedef enum {
NPDrawingModelSyncX = 6,
NPDrawingModelAsyncBitmapSurface = 7
#if defined(XP_WIN)
, NPDrawingModelAsyncWindowsDXGISurface = 8,
NPDrawingModelAsyncWindowsDX9ExSurface = 9
, NPDrawingModelAsyncWindowsDXGISurface = 8
#endif
} NPDrawingModel;
@ -462,11 +461,9 @@ typedef enum {
, NPNVsupportsCoreAnimationBool = 2003
, NPNVsupportsInvalidatingCoreAnimationBool = 2004
#endif
, NPNVsupportsSyncDrawingBool = 2005
, NPNVsupportsAsyncBitmapSurfaceBool = 2006
, NPNVsupportsAsyncBitmapSurfaceBool = 2005
#if defined(XP_WIN)
, NPNVsupportsAsyncWindowsDXGISurfaceBool = 2007
, NPNVsupportsAsyncWindowsDX9ExSurfaceBool = 2008
, NPNVsupportsAsyncWindowsDXGISurfaceBool = 2006
#endif
#if defined(XP_MACOSX)

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

@ -93,7 +93,6 @@ inline bool IsDrawingModelAsync(int16_t aModel) {
return aModel == NPDrawingModelAsyncBitmapSurface
#ifdef XP_WIN
|| aModel == NPDrawingModelAsyncWindowsDXGISurface
|| aModel == NPDrawingModelAsyncWindowsDX9ExSurface
#endif
;
}

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

@ -1244,6 +1244,8 @@ DOMStorageImpl::RemoveValue(bool aCallerSecure, const nsAString& aKey,
nsresult rv = InitDB();
NS_ENSURE_SUCCESS(rv, rv);
CacheKeysFromDB();
nsAutoString value;
bool secureItem;
rv = GetDBValue(aKey, value, &secureItem);

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

@ -21,6 +21,15 @@ const browserFrameHelpers = {
}
},
'getOOPDisabledPref': function() {
try {
return SpecialPowers.getBoolPref('dom.ipc.tabs.disabled');
}
catch(e) {
return undefined;
}
},
'setEnabledPref': function(enabled) {
if (enabled !== undefined) {
SpecialPowers.setBoolPref('dom.mozBrowserFramesEnabled', enabled);
@ -39,6 +48,15 @@ const browserFrameHelpers = {
}
},
'setOOPDisabledPref': function(value) {
if (value !== undefined) {
SpecialPowers.setBoolPref('dom.ipc.tabs.disabled', value);
}
else {
SpecialPowers.clearUserPref('dom.ipc.tabs.disabled');
}
},
'addToWhitelist': function() {
var whitelist = browserFrameHelpers.getWhitelistPref();
whitelist += ', http://' + window.location.host + ', ';
@ -48,10 +66,12 @@ const browserFrameHelpers = {
'restoreOriginalPrefs': function() {
browserFrameHelpers.setEnabledPref(browserFrameHelpers.origEnabledPref);
browserFrameHelpers.setWhitelistPref(browserFrameHelpers.origWhitelistPref);
browserFrameHelpers.setOOPDisabledPref(browserFrameHelpers.origOOPDisabledPref);
},
'origEnabledPref': null,
'origWhitelistPref': null,
'origOOPDisabledPref': null,
// Two basically-empty pages from two different domains you can load.
'emptyPage1': 'http://example.com' +
@ -64,6 +84,11 @@ const browserFrameHelpers = {
browserFrameHelpers.origEnabledPref = browserFrameHelpers.getEnabledPref();
browserFrameHelpers.origWhitelistPref = browserFrameHelpers.getWhitelistPref();
browserFrameHelpers.origOOPDisabledPref = browserFrameHelpers.getOOPDisabledPref();
// Set OOPDisabledPref to true, because none of these tests pass with OOP
// browser frames, at the moment.
browserFrameHelpers.setOOPDisabledPref(true);
addEventListener('unload', function() {
browserFrameHelpers.restoreOriginalPrefs();

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

@ -64,6 +64,8 @@ _TEST_FILES = \
pbSwitch.js \
test_brokenUTF-16.html \
test_bug624047.html \
test_bug746272-1.html \
test_bug746272-2.html \
test_cookieBlock.html \
test_cookieSession-phase1.html \
test_cookieSession-phase2.html \

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

@ -0,0 +1,32 @@
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>incomplete UTF-16 test</title>
<meta http-equiv="Content-type" content="text/html; charset=UTF-8" />
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
<script type="text/javascript">
function startTest()
{
localStorage.clear();
localStorage.setItem("test1", "value1");
localStorage.setItem("test2", "value2");
localStorage.setItem("test3", "value3");
is(localStorage.length, 3, "expected number of items");
SimpleTest.finish();
}
SimpleTest.waitForExplicitFinish();
</script>
</head>
<body onload="startTest();">
</body>
</html>

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

@ -0,0 +1,31 @@
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>incomplete UTF-16 test</title>
<meta http-equiv="Content-type" content="text/html; charset=UTF-8" />
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
<script type="text/javascript">
function startTest()
{
var test2 = localStorage.getItem("test2");
is(test2, "value2", "expected item");
localStorage.removeItem("test2");
is(localStorage.length, 2, "expected number of items");
SimpleTest.finish();
}
SimpleTest.waitForExplicitFinish();
</script>
</head>
<body onload="startTest();">
</body>
</html>

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

@ -43,6 +43,7 @@
#include "jsfriendapi.h"
#include "jsprf.h"
#include "mozilla/Util.h"
#include "nsDOMException.h"
#include "nsTraceRefcnt.h"
#include "WorkerInlines.h"
@ -68,6 +69,7 @@ class DOMException : public PrivatizableBase
enum SLOT {
SLOT_code = 0,
SLOT_name,
SLOT_message,
SLOT_COUNT
};
@ -87,7 +89,7 @@ public:
}
static JSObject*
Create(JSContext* aCx, int aCode);
Create(JSContext* aCx, nsresult aNSResult);
private:
DOMException()
@ -131,18 +133,23 @@ private:
return false;
}
char buf[100];
JS_snprintf(buf, sizeof(buf), "%s: ", sClass.name);
jsval name = JS_GetReservedSlot(obj, SLOT_name);
JS_ASSERT(name.isString());
JSString* classString = JS_NewStringCopyZ(aCx, buf);
if (!classString) {
JSString *colon = JS_NewStringCopyN(aCx, ": ", 2);
if (!colon){
return false;
}
jsval name = JS_GetReservedSlot(obj, SLOT_name);
JS_ASSERT(JSVAL_IS_STRING(name));
JSString* out = JS_ConcatStrings(aCx, name.toString(), colon);
if (!out) {
return false;
}
JSString* out = JS_ConcatStrings(aCx, classString, JSVAL_TO_STRING(name));
jsval message = JS_GetReservedSlot(obj, SLOT_message);
JS_ASSERT(message.isString());
out = JS_ConcatStrings(aCx, out, message.toString());
if (!out) {
return false;
}
@ -190,6 +197,7 @@ JSClass DOMException::sClass = {
JSPropertySpec DOMException::sProperties[] = {
{ "code", SLOT_code, PROPERTY_FLAGS, GetProperty, js_GetterOnlyPropertyStub },
{ "name", SLOT_name, PROPERTY_FLAGS, GetProperty, js_GetterOnlyPropertyStub },
{ "message", SLOT_message, PROPERTY_FLAGS, GetProperty, js_GetterOnlyPropertyStub },
{ 0, 0, 0, NULL, NULL }
};
@ -203,9 +211,6 @@ JSPropertySpec DOMException::sStaticProperties[] = {
#define EXCEPTION_ENTRY(_name) \
{ #_name, _name, CONSTANT_FLAGS, GetConstant, NULL },
// Make sure this one is always first.
EXCEPTION_ENTRY(UNKNOWN_ERR)
EXCEPTION_ENTRY(INDEX_SIZE_ERR)
EXCEPTION_ENTRY(DOMSTRING_SIZE_ERR)
EXCEPTION_ENTRY(HIERARCHY_REQUEST_ERR)
@ -239,32 +244,35 @@ JSPropertySpec DOMException::sStaticProperties[] = {
// static
JSObject*
DOMException::Create(JSContext* aCx, int aCode)
DOMException::Create(JSContext* aCx, nsresult aNSResult)
{
JSObject* obj = JS_NewObject(aCx, &sClass, NULL, NULL);
if (!obj) {
return NULL;
}
size_t foundIndex = size_t(-1);
for (size_t index = 0; index < ArrayLength(sStaticProperties) - 1; index++) {
if (sStaticProperties[index].tinyid == aCode) {
foundIndex = index;
break;
}
}
if (foundIndex == size_t(-1)) {
foundIndex = 0;
}
JSString* name = JS_NewStringCopyZ(aCx, sStaticProperties[foundIndex].name);
if (!name) {
const char* name;
const char* message;
uint16_t code;
if (NS_FAILED(NS_GetNameAndMessageForDOMNSResult(aNSResult, &name, &message,
&code))) {
JS_ReportError(aCx, "Exception thrown (nsresult = 0x%x).", aNSResult);
return NULL;
}
JS_SetReservedSlot(obj, SLOT_code, INT_TO_JSVAL(aCode));
JS_SetReservedSlot(obj, SLOT_name, STRING_TO_JSVAL(name));
JSString* jsname = JS_NewStringCopyZ(aCx, name);
if (!jsname) {
return NULL;
}
JSString* jsmessage = JS_NewStringCopyZ(aCx, message);
if (!jsmessage) {
return NULL;
}
JS_SetReservedSlot(obj, SLOT_code, INT_TO_JSVAL(code));
JS_SetReservedSlot(obj, SLOT_name, STRING_TO_JSVAL(jsname));
JS_SetReservedSlot(obj, SLOT_message, STRING_TO_JSVAL(jsmessage));
DOMException* priv = new DOMException();
SetJSPrivateSafeish(obj, priv);
@ -272,147 +280,6 @@ DOMException::Create(JSContext* aCx, int aCode)
return obj;
}
class FileException : public PrivatizableBase
{
static JSClass sClass;
static JSPropertySpec sProperties[];
static JSPropertySpec sStaticProperties[];
enum SLOT {
SLOT_code = 0,
SLOT_name,
SLOT_COUNT
};
public:
static JSObject*
InitClass(JSContext* aCx, JSObject* aObj)
{
return JS_InitClass(aCx, aObj, NULL, &sClass, Construct, 0, sProperties,
NULL, sStaticProperties, NULL);
}
static JSObject*
Create(JSContext* aCx, int aCode);
private:
FileException()
{
MOZ_COUNT_CTOR(mozilla::dom::workers::exceptions::FileException);
}
~FileException()
{
MOZ_COUNT_DTOR(mozilla::dom::workers::exceptions::FileException);
}
static JSBool
Construct(JSContext* aCx, unsigned aArgc, jsval* aVp)
{
JS_ReportErrorNumber(aCx, js_GetErrorMessage, NULL, JSMSG_WRONG_CONSTRUCTOR,
sClass.name);
return false;
}
static void
Finalize(JSFreeOp* aFop, JSObject* aObj)
{
JS_ASSERT(JS_GetClass(aObj) == &sClass);
delete GetJSPrivateSafeish<FileException>(aObj);
}
static JSBool
GetProperty(JSContext* aCx, JSObject* aObj, jsid aIdval, jsval* aVp)
{
JS_ASSERT(JSID_IS_INT(aIdval));
int32 slot = JSID_TO_INT(aIdval);
JSClass* classPtr = JS_GetClass(aObj);
if (classPtr != &sClass || !GetJSPrivateSafeish<FileException>(aObj)) {
JS_ReportErrorNumber(aCx, js_GetErrorMessage, NULL,
JSMSG_INCOMPATIBLE_PROTO, sClass.name,
sProperties[slot].name, classPtr->name);
return false;
}
*aVp = JS_GetReservedSlot(aObj, slot);
return true;
}
static JSBool
GetConstant(JSContext* aCx, JSObject* aObj, jsid idval, jsval* aVp)
{
JS_ASSERT(JSID_IS_INT(idval));
*aVp = INT_TO_JSVAL(JSID_TO_INT(idval));
return true;
}
};
JSClass FileException::sClass = {
"FileException",
JSCLASS_HAS_PRIVATE | JSCLASS_HAS_RESERVED_SLOTS(SLOT_COUNT),
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, Finalize
};
JSPropertySpec FileException::sProperties[] = {
{ "code", SLOT_code, PROPERTY_FLAGS, GetProperty, js_GetterOnlyPropertyStub },
{ "name", SLOT_name, PROPERTY_FLAGS, GetProperty, js_GetterOnlyPropertyStub },
{ 0, 0, 0, NULL, NULL }
};
JSPropertySpec FileException::sStaticProperties[] = {
#define EXCEPTION_ENTRY(_name) \
{ #_name, FILE_##_name, CONSTANT_FLAGS, GetConstant, NULL },
EXCEPTION_ENTRY(NOT_FOUND_ERR)
EXCEPTION_ENTRY(SECURITY_ERR)
EXCEPTION_ENTRY(ABORT_ERR)
EXCEPTION_ENTRY(NOT_READABLE_ERR)
EXCEPTION_ENTRY(ENCODING_ERR)
#undef EXCEPTION_ENTRY
{ 0, 0, 0, NULL, NULL }
};
// static
JSObject*
FileException::Create(JSContext* aCx, int aCode)
{
JSObject* obj = JS_NewObject(aCx, &sClass, NULL, NULL);
if (!obj) {
return NULL;
}
size_t foundIndex = size_t(-1);
for (size_t index = 0; index < ArrayLength(sStaticProperties) - 1; index++) {
if (sStaticProperties[index].tinyid == aCode) {
foundIndex = index;
break;
}
}
JS_ASSERT(foundIndex != size_t(-1));
JSString* name = JS_NewStringCopyZ(aCx, sStaticProperties[foundIndex].name);
if (!name) {
return NULL;
}
JS_SetReservedSlot(obj, SLOT_code, INT_TO_JSVAL(aCode));
JS_SetReservedSlot(obj, SLOT_name, STRING_TO_JSVAL(name));
FileException* priv = new FileException();
SetJSPrivateSafeish(obj, priv);
return obj;
}
} // anonymous namespace
BEGIN_WORKERS_NAMESPACE
@ -422,24 +289,16 @@ namespace exceptions {
bool
InitClasses(JSContext* aCx, JSObject* aGlobal)
{
return DOMException::InitClass(aCx, aGlobal) &&
FileException::InitClass(aCx, aGlobal);
return DOMException::InitClass(aCx, aGlobal);
}
void
ThrowDOMExceptionForCode(JSContext* aCx, int aCode)
ThrowDOMExceptionForNSResult(JSContext* aCx, nsresult aNSResult)
{
JSObject* exception = DOMException::Create(aCx, aCode);
JS_ASSERT(exception);
JS_SetPendingException(aCx, OBJECT_TO_JSVAL(exception));
}
void
ThrowFileExceptionForCode(JSContext* aCx, int aCode)
{
JSObject* exception = FileException::Create(aCx, aCode);
JS_ASSERT(exception);
JSObject* exception = DOMException::Create(aCx, aNSResult);
if (!exception) {
return;
}
JS_SetPendingException(aCx, OBJECT_TO_JSVAL(exception));
}

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

@ -71,16 +71,6 @@
#define INVALID_NODE_TYPE_ERR 24
#define DATA_CLONE_ERR 25
// This one isn't actually spec'd anywhere, use it when we can't find a match.
#define UNKNOWN_ERR 0
// FileException Codes
#define FILE_NOT_FOUND_ERR 1
#define FILE_SECURITY_ERR 2
#define FILE_ABORT_ERR 3
#define FILE_NOT_READABLE_ERR 4
#define FILE_ENCODING_ERR 5
BEGIN_WORKERS_NAMESPACE
namespace exceptions {
@ -88,12 +78,6 @@ namespace exceptions {
bool
InitClasses(JSContext* aCx, JSObject* aGlobal);
void
ThrowDOMExceptionForCode(JSContext* aCx, int aCode);
void
ThrowFileExceptionForCode(JSContext* aCx, int aCode);
} // namespace exceptions
END_WORKERS_NAMESPACE

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

@ -41,6 +41,7 @@
#include "nsIDOMFile.h"
#include "nsDOMBlobBuilder.h"
#include "nsDOMError.h"
#include "jsapi.h"
#include "jsatom.h"
@ -58,8 +59,7 @@
USING_WORKERS_NAMESPACE
using mozilla::dom::workers::exceptions::ThrowDOMExceptionForCode;
using mozilla::dom::workers::exceptions::ThrowFileExceptionForCode;
using mozilla::dom::workers::exceptions::ThrowDOMExceptionForNSResult;
namespace {
@ -125,9 +125,7 @@ private:
nsresult rv = file->InitInternal(aCx, aArgc, JS_ARGV(aCx, aVp),
Unwrap);
if (NS_FAILED(rv)) {
ThrowDOMExceptionForCode(aCx,
NS_ERROR_GET_MODULE(rv) == NS_ERROR_MODULE_DOM ?
NS_ERROR_GET_CODE(rv) : UNKNOWN_ERR);
ThrowDOMExceptionForNSResult(aCx, rv);
return false;
}
@ -159,7 +157,8 @@ private:
PRUint64 size;
if (NS_FAILED(blob->GetSize(&size))) {
ThrowFileExceptionForCode(aCx, FILE_NOT_READABLE_ERR);
ThrowDOMExceptionForNSResult(aCx, NS_ERROR_DOM_FILE_NOT_READABLE_ERR);
return false;
}
if (!JS_NewNumberValue(aCx, double(size), aVp)) {
@ -179,7 +178,8 @@ private:
nsString type;
if (NS_FAILED(blob->GetType(type))) {
ThrowFileExceptionForCode(aCx, FILE_NOT_READABLE_ERR);
ThrowDOMExceptionForNSResult(aCx, NS_ERROR_DOM_FILE_NOT_READABLE_ERR);
return false;
}
JSString* jsType = JS_NewUCStringCopyN(aCx, type.get(), type.Length());
@ -223,7 +223,7 @@ private:
static_cast<PRUint64>(end),
contentType, optionalArgc,
getter_AddRefs(rtnBlob)))) {
ThrowFileExceptionForCode(aCx, FILE_NOT_READABLE_ERR);
ThrowDOMExceptionForNSResult(aCx, NS_ERROR_DOM_FILE_NOT_READABLE_ERR);
return false;
}
@ -350,7 +350,7 @@ private:
if (GetWorkerPrivateFromContext(aCx)->UsesSystemPrincipal() &&
NS_FAILED(file->GetMozFullPathInternal(fullPath))) {
ThrowFileExceptionForCode(aCx, FILE_NOT_READABLE_ERR);
ThrowDOMExceptionForNSResult(aCx, NS_ERROR_DOM_FILE_NOT_READABLE_ERR);
return false;
}

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

@ -40,6 +40,7 @@
#include "FileReaderSync.h"
#include "nsIDOMFile.h"
#include "nsDOMError.h"
#include "jsapi.h"
#include "jsatom.h"
@ -56,7 +57,7 @@
USING_WORKERS_NAMESPACE
using mozilla::dom::workers::exceptions::ThrowFileExceptionForCode;
using mozilla::dom::workers::exceptions::ThrowDOMExceptionForNSResult;
namespace {
@ -67,10 +68,10 @@ EnsureSucceededOrThrow(JSContext* aCx, nsresult rv)
return true;
}
int code = rv == NS_ERROR_FILE_NOT_FOUND ?
FILE_NOT_FOUND_ERR :
FILE_NOT_READABLE_ERR;
ThrowFileExceptionForCode(aCx, code);
rv = rv == NS_ERROR_FILE_NOT_FOUND ?
NS_ERROR_DOM_FILE_NOT_FOUND_ERR :
NS_ERROR_DOM_FILE_NOT_READABLE_ERR;
ThrowDOMExceptionForNSResult(aCx, rv);
return false;
}

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

@ -100,7 +100,7 @@
using mozilla::MutexAutoLock;
using mozilla::TimeDuration;
using mozilla::TimeStamp;
using mozilla::dom::workers::exceptions::ThrowDOMExceptionForCode;
using mozilla::dom::workers::exceptions::ThrowDOMExceptionForNSResult;
USING_WORKERS_NAMESPACE
using namespace mozilla::dom::workers::events;
@ -415,7 +415,7 @@ struct WorkerStructuredCloneCallbacks
static void
Error(JSContext* aCx, uint32_t /* aErrorId */)
{
ThrowDOMExceptionForCode(aCx, DATA_CLONE_ERR);
ThrowDOMExceptionForNSResult(aCx, NS_ERROR_DOM_DATA_CLONE_ERR);
}
};

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

@ -97,6 +97,14 @@ GetWorkerCrossThreadDispatcher(JSContext* aCx, jsval aWorker);
// Random unique constant to facilitate JSPrincipal debugging
const uint32_t kJSPrincipalsDebugToken = 0x7e2df9d2;
namespace exceptions {
// Implemented in Exceptions.cpp
void
ThrowDOMExceptionForNSResult(JSContext* aCx, nsresult aNSResult);
} // namespace exceptions
END_WORKERS_NAMESPACE
#endif // mozilla_dom_workers_workers_h__

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

@ -34,7 +34,7 @@ USING_WORKERS_NAMESPACE
namespace XMLHttpRequestResponseTypeValues =
mozilla::dom::bindings::prototypes::XMLHttpRequestResponseType;
using mozilla::dom::workers::exceptions::ThrowDOMExceptionForCode;
using mozilla::dom::workers::exceptions::ThrowDOMExceptionForNSResult;
// XXX Need to figure this out...
#define UNCATCHABLE_EXCEPTION NS_ERROR_OUT_OF_MEMORY
@ -214,21 +214,6 @@ END_WORKERS_NAMESPACE
namespace {
inline int
GetDOMExceptionCodeFromResult(nsresult aResult)
{
if (NS_SUCCEEDED(aResult)) {
return 0;
}
if (NS_ERROR_GET_MODULE(aResult) == NS_ERROR_MODULE_DOM) {
return NS_ERROR_GET_CODE(aResult);
}
NS_WARNING("Update main thread implementation for a DOM error code here!");
return INVALID_STATE_ERR;
}
inline void
ConvertResponseTypeToString(XMLHttpRequestResponseType aType, nsString& aString)
{
@ -783,11 +768,11 @@ private:
class ResponseRunnable : public MainThreadProxyRunnable
{
PRUint32 mSyncQueueKey;
int mErrorCode;
nsresult mErrorCode;
public:
ResponseRunnable(WorkerPrivate* aWorkerPrivate, Proxy* aProxy,
PRUint32 aSyncQueueKey, int aErrorCode)
PRUint32 aSyncQueueKey, nsresult aErrorCode)
: MainThreadProxyRunnable(aWorkerPrivate, SkipWhenClearing, aProxy),
mSyncQueueKey(aSyncQueueKey), mErrorCode(aErrorCode)
{
@ -797,8 +782,8 @@ private:
bool
WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate)
{
if (mErrorCode) {
ThrowDOMExceptionForCode(aCx, mErrorCode);
if (NS_FAILED(mErrorCode)) {
ThrowDOMExceptionForNSResult(aCx, mErrorCode);
aWorkerPrivate->StopSyncLoop(mSyncQueueKey, false);
}
else {
@ -836,7 +821,7 @@ public:
return true;
}
virtual int
virtual nsresult
MainThreadRun() = 0;
NS_IMETHOD
@ -847,7 +832,7 @@ public:
PRUint32 oldSyncQueueKey = mProxy->mSyncEventResponseSyncQueueKey;
mProxy->mSyncEventResponseSyncQueueKey = mSyncQueueKey;
int rv = MainThreadRun();
nsresult rv = MainThreadRun();
nsRefPtr<ResponseRunnable> response =
new ResponseRunnable(mWorkerPrivate, mProxy, mSyncQueueKey, rv);
@ -871,7 +856,7 @@ public:
MOZ_ASSERT(aProxy);
}
virtual int
virtual nsresult
MainThreadRun()
{
AssertIsOnMainThread();
@ -892,10 +877,10 @@ public:
: WorkerThreadProxySyncRunnable(aWorkerPrivate, aProxy), mValue(aValue)
{ }
int
nsresult
MainThreadRun()
{
return GetDOMExceptionCodeFromResult(mProxy->mXHR->SetMultipart(mValue));
return mProxy->mXHR->SetMultipart(mValue);
}
};
@ -909,11 +894,10 @@ public:
: WorkerThreadProxySyncRunnable(aWorkerPrivate, aProxy), mValue(aValue)
{ }
int
nsresult
MainThreadRun()
{
nsresult rv = mProxy->mXHR->SetMozBackgroundRequest(mValue);
return GetDOMExceptionCodeFromResult(rv);
return mProxy->mXHR->SetMozBackgroundRequest(mValue);
}
};
@ -927,11 +911,10 @@ public:
: WorkerThreadProxySyncRunnable(aWorkerPrivate, aProxy), mValue(aValue)
{ }
int
nsresult
MainThreadRun()
{
nsresult rv = mProxy->mXHR->SetWithCredentials(mValue);
return GetDOMExceptionCodeFromResult(rv);
return mProxy->mXHR->SetWithCredentials(mValue);
}
};
@ -946,7 +929,7 @@ public:
mResponseType(aResponseType)
{ }
int
nsresult
MainThreadRun()
{
nsresult rv = mProxy->mXHR->SetResponseType(mResponseType);
@ -954,7 +937,7 @@ public:
if (NS_SUCCEEDED(rv)) {
rv = mProxy->mXHR->GetResponseType(mResponseType);
}
return GetDOMExceptionCodeFromResult(rv);
return rv;
}
void
@ -974,10 +957,10 @@ public:
mTimeout(aTimeout)
{ }
int
nsresult
MainThreadRun()
{
return GetDOMExceptionCodeFromResult(mProxy->mXHR->SetTimeout(mTimeout));
return mProxy->mXHR->SetTimeout(mTimeout);
}
};
@ -988,7 +971,7 @@ public:
: WorkerThreadProxySyncRunnable(aWorkerPrivate, aProxy)
{ }
int
nsresult
MainThreadRun()
{
mProxy->mInnerEventStreamId++;
@ -1002,7 +985,7 @@ public:
mProxy->Reset();
return 0;
return NS_OK;
}
};
@ -1017,11 +1000,11 @@ public:
mResponseHeaders(aResponseHeaders)
{ }
int
nsresult
MainThreadRun()
{
mProxy->mXHR->GetAllResponseHeaders(mResponseHeaders);
return 0;
return NS_OK;
}
};
@ -1037,11 +1020,10 @@ public:
mValue(aValue)
{ }
int
nsresult
MainThreadRun()
{
nsresult rv = mProxy->mXHR->GetResponseHeader(mHeader, mValue);
return GetDOMExceptionCodeFromResult(rv);
return mProxy->mXHR->GetResponseHeader(mHeader, mValue);
}
};
@ -1068,53 +1050,45 @@ public:
mTimeout(aTimeout)
{ }
int
nsresult
MainThreadRun()
{
WorkerPrivate* oldWorker = mProxy->mWorkerPrivate;
mProxy->mWorkerPrivate = mWorkerPrivate;
int retval = MainThreadRunInternal();
nsresult rv = MainThreadRunInternal();
mProxy->mWorkerPrivate = oldWorker;
return retval;
return rv;
}
int
nsresult
MainThreadRunInternal()
{
if (!mProxy->Init()) {
return INVALID_STATE_ERR;
return NS_ERROR_DOM_INVALID_STATE_ERR;
}
nsresult rv;
if (mMultipart) {
rv = mProxy->mXHR->SetMultipart(mMultipart);
if (NS_FAILED(rv)) {
return GetDOMExceptionCodeFromResult(rv);
}
NS_ENSURE_SUCCESS(rv, rv);
}
if (mBackgroundRequest) {
rv = mProxy->mXHR->SetMozBackgroundRequest(mBackgroundRequest);
if (NS_FAILED(rv)) {
return GetDOMExceptionCodeFromResult(rv);
}
NS_ENSURE_SUCCESS(rv, rv);
}
if (mWithCredentials) {
rv = mProxy->mXHR->SetWithCredentials(mWithCredentials);
if (NS_FAILED(rv)) {
return GetDOMExceptionCodeFromResult(rv);
}
NS_ENSURE_SUCCESS(rv, rv);
}
if (mTimeout) {
rv = mProxy->mXHR->SetTimeout(mTimeout);
if (NS_FAILED(rv)) {
return GetDOMExceptionCodeFromResult(rv);
}
NS_ENSURE_SUCCESS(rv, rv);
}
NS_ASSERTION(!mProxy->mInOpen, "Reentrancy is bad!");
@ -1129,7 +1103,7 @@ public:
rv = mProxy->mXHR->SetResponseType(NS_LITERAL_STRING("text"));
}
return GetDOMExceptionCodeFromResult(rv);
return rv;
}
};
@ -1154,7 +1128,7 @@ public:
mClonedObjects.SwapElements(aClonedObjects);
}
int
nsresult
MainThreadRun()
{
nsCOMPtr<nsIVariant> variant;
@ -1164,7 +1138,7 @@ public:
nsIXPConnect* xpc = nsContentUtils::XPConnect();
NS_ASSERTION(xpc, "This should never be null!");
int error = 0;
nsresult rv = NS_OK;
JSStructuredCloneCallbacks* callbacks =
mWorkerPrivate->IsChromeWorker() ?
@ -1175,24 +1149,22 @@ public:
if (mBody.read(cx, &body, callbacks, &mClonedObjects)) {
if (NS_FAILED(xpc->JSValToVariant(cx, &body,
getter_AddRefs(variant)))) {
error = INVALID_STATE_ERR;
rv = NS_ERROR_DOM_INVALID_STATE_ERR;
}
}
else {
error = DATA_CLONE_ERR;
rv = NS_ERROR_DOM_DATA_CLONE_ERR;
}
mBody.clear();
mClonedObjects.Clear();
if (error) {
return error;
}
NS_ENSURE_SUCCESS(rv, rv);
}
else {
nsCOMPtr<nsIWritableVariant> wvariant =
do_CreateInstance(NS_VARIANT_CONTRACTID);
NS_ENSURE_TRUE(wvariant, UNKNOWN_ERR);
NS_ENSURE_TRUE(wvariant, NS_ERROR_UNEXPECTED);
if (NS_FAILED(wvariant->SetAsAString(mStringBody))) {
NS_ERROR("This should never fail!");
@ -1229,7 +1201,7 @@ public:
}
}
return GetDOMExceptionCodeFromResult(rv);
return rv;
}
};
@ -1245,11 +1217,10 @@ public:
mValue(aValue)
{ }
int
nsresult
MainThreadRun()
{
nsresult rv = mProxy->mXHR->SetRequestHeader(mHeader, mValue);
return GetDOMExceptionCodeFromResult(rv);
return mProxy->mXHR->SetRequestHeader(mHeader, mValue);
}
};
@ -1263,11 +1234,11 @@ public:
: WorkerThreadProxySyncRunnable(aWorkerPrivate, aProxy), mMimeType(aMimeType)
{ }
int
nsresult
MainThreadRun()
{
mProxy->mXHR->OverrideMimeType(mMimeType);
return 0;
return NS_OK;
}
};

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

@ -66,6 +66,16 @@ onmessage = function(event) {
throw new Error("Failed to throw when getting responseText on '" + type +
"' type");
}
if (exception.name != "InvalidStateError") {
throw new Error("Unexpected error when getting responseText on '" + type +
"' type");
}
if (exception.code != DOMException.INVALID_STATE_ERR) {
throw new Error("Unexpected error code when getting responseText on '" + type +
"' type");
}
}
testResponseTextException("arraybuffer");
@ -102,6 +112,16 @@ onmessage = function(event) {
"calling open()");
}
if (exception.name != "InvalidStateError") {
throw new Error("Unexpected error when setting responseType before " +
"calling open()");
}
if (exception.code != DOMException.INVALID_STATE_ERR) {
throw new Error("Unexpected error code when setting responseType before " +
"calling open()");
}
xhr.open("GET", url);
xhr.responseType = "text";
xhr.onload = function(event) {
@ -152,4 +172,14 @@ onmessage = function(event) {
throw new Error("Failed to throw when setting responseType after " +
"calling send()");
}
if (exception.name != "InvalidStateError") {
throw new Error("Unexpected error when setting responseType after " +
"calling send()");
}
if (exception.code != DOMException.INVALID_STATE_ERR) {
throw new Error("Unexpected error code when setting responseType after " +
"calling send()");
}
}

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

@ -42,6 +42,7 @@
#include <string.h>
#include <stdio.h>
#include <algorithm>
#include "prlink.h"
#include "prenv.h"
@ -1295,361 +1296,334 @@ PRUint32 TiledTextureImage::GetTileCount()
return mImages.Length();
}
bool
GLContext::ResizeOffscreenFBO(const gfxIntSize& aSize, const bool aUseReadFBO, const bool aDisableAA)
GLContext::GLFormats
GLContext::ChooseGLFormats(ContextFormat& aCF)
{
if (!IsOffscreenSizeAllowed(aSize))
return false;
GLFormats formats;
MakeCurrent();
if (aCF.alpha) {
formats.texColor = LOCAL_GL_RGBA;
if (mIsGLES2 && !IsExtensionSupported(OES_rgb8_rgba8)) {
formats.rbColor = LOCAL_GL_RGBA4;
aCF.red = aCF.green = aCF.blue = aCF.alpha = 4;
} else {
formats.rbColor = LOCAL_GL_RGBA8;
aCF.red = aCF.green = aCF.blue = aCF.alpha = 8;
}
} else {
formats.texColor = LOCAL_GL_RGB;
if (mIsGLES2 && !IsExtensionSupported(OES_rgb8_rgba8)) {
formats.rbColor = LOCAL_GL_RGB565;
aCF.red = 5;
aCF.green = 6;
aCF.blue = 5;
} else {
formats.rbColor = LOCAL_GL_RGB8;
aCF.red = aCF.green = aCF.blue = 8;
}
aCF.alpha = 0;
}
formats.texColorType = LOCAL_GL_UNSIGNED_BYTE;
const bool alpha = mCreationFormat.alpha > 0;
const int depth = mCreationFormat.depth;
const int stencil = mCreationFormat.stencil;
int samples = mCreationFormat.samples;
GLint maxSamples = 0;
if (SupportsFramebufferMultisample() && !aDisableAA)
fGetIntegerv(LOCAL_GL_MAX_SAMPLES, &maxSamples);
GLsizei samples = aCF.samples;
GLsizei maxSamples = 0;
if (SupportsFramebufferMultisample())
fGetIntegerv(LOCAL_GL_MAX_SAMPLES, (GLint*)&maxSamples);
samples = NS_MIN(samples, maxSamples);
const bool useDrawMSFBO = (samples > 0);
formats.samples = samples;
aCF.samples = samples;
if (!useDrawMSFBO && !aUseReadFBO) {
// Early out, as no FBO resize work is necessary.
const int depth = aCF.depth;
const int stencil = aCF.stencil;
const bool useDepthStencil =
!mIsGLES2 || IsExtensionSupported(OES_packed_depth_stencil);
formats.depthStencil = 0;
formats.depth = 0;
formats.stencil = 0;
if (depth && stencil && useDepthStencil) {
formats.depthStencil = LOCAL_GL_DEPTH24_STENCIL8;
aCF.depth = 24;
aCF.stencil = 8;
} else {
if (depth) {
if (mIsGLES2) {
if (IsExtensionSupported(OES_depth24)) {
formats.depth = LOCAL_GL_DEPTH_COMPONENT24;
aCF.depth = 24;
} else {
formats.depth = LOCAL_GL_DEPTH_COMPONENT16;
aCF.depth = 16;
}
} else {
formats.depth = LOCAL_GL_DEPTH_COMPONENT24;
aCF.depth = 24;
}
}
if (stencil) {
formats.stencil = LOCAL_GL_STENCIL_INDEX8;
aCF.stencil = 8;
}
}
return formats;
}
void
GLContext::CreateTextureForOffscreen(const GLFormats& aFormats, const gfxIntSize& aSize, GLuint& texture)
{
GLuint boundTexture = 0;
fGetIntegerv(LOCAL_GL_TEXTURE_BINDING_2D, (GLint*)&boundTexture);
texture = 0;
fGenTextures(1, &texture);
fBindTexture(LOCAL_GL_TEXTURE_2D, texture);
fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MIN_FILTER, LOCAL_GL_LINEAR);
fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MAG_FILTER, LOCAL_GL_LINEAR);
fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_S, LOCAL_GL_CLAMP_TO_EDGE);
fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_T, LOCAL_GL_CLAMP_TO_EDGE);
fTexImage2D(LOCAL_GL_TEXTURE_2D,
0,
aFormats.texColor,
aSize.width, aSize.height,
0,
aFormats.texColor,
aFormats.texColorType,
nsnull);
fBindTexture(LOCAL_GL_TEXTURE_2D, boundTexture);
}
static inline void
RenderbufferStorageBySamples(GLContext* gl, GLsizei samples, GLenum internalFormat, const gfxIntSize& size)
{
if (samples) {
gl->fRenderbufferStorageMultisample(LOCAL_GL_RENDERBUFFER,
samples,
internalFormat,
size.width, size.height);
} else {
gl->fRenderbufferStorage(LOCAL_GL_RENDERBUFFER,
internalFormat,
size.width, size.height);
}
}
void
GLContext::CreateRenderbuffersForOffscreen(const GLContext::GLFormats& aFormats, const gfxIntSize& aSize,
GLuint& colorMSRB, GLuint& depthRB, GLuint& stencilRB)
{
GLuint boundRB = 0;
fGetIntegerv(LOCAL_GL_RENDERBUFFER_BINDING, (GLint*)&boundRB);
colorMSRB = 0;
depthRB = 0;
stencilRB = 0;
if (aFormats.samples > 0) {
fGenRenderbuffers(1, &colorMSRB);
fBindRenderbuffer(LOCAL_GL_RENDERBUFFER, colorMSRB);
RenderbufferStorageBySamples(this, aFormats.samples, aFormats.rbColor, aSize);
}
// If depthStencil, disallow depth, stencil
MOZ_ASSERT(!aFormats.depthStencil || (!aFormats.depth && !aFormats.stencil));
if (aFormats.depthStencil) {
fGenRenderbuffers(1, &depthRB);
stencilRB = depthRB;
fBindRenderbuffer(LOCAL_GL_RENDERBUFFER, depthRB);
RenderbufferStorageBySamples(this, aFormats.samples, aFormats.depthStencil, aSize);
}
if (aFormats.depth) {
fGenRenderbuffers(1, &depthRB);
fBindRenderbuffer(LOCAL_GL_RENDERBUFFER, depthRB);
RenderbufferStorageBySamples(this, aFormats.samples, aFormats.depth, aSize);
}
if (aFormats.stencil) {
fGenRenderbuffers(1, &stencilRB);
fBindRenderbuffer(LOCAL_GL_RENDERBUFFER, stencilRB);
RenderbufferStorageBySamples(this, aFormats.samples, aFormats.stencil, aSize);
}
fBindRenderbuffer(LOCAL_GL_RENDERBUFFER, boundRB);
}
bool
GLContext::AssembleOffscreenFBOs(const GLuint colorMSRB,
const GLuint depthRB,
const GLuint stencilRB,
const GLuint texture,
GLuint& drawFBO,
GLuint& readFBO)
{
drawFBO = 0;
readFBO = 0;
if (!colorMSRB && !texture) {
MOZ_ASSERT(!depthRB && !stencilRB);
return true;
}
GLuint curBoundFramebufferDraw = 0;
GLuint curBoundFramebufferRead = 0;
GLuint curBoundRenderbuffer = 0;
GLuint curBoundTexture = 0;
GLuint boundDrawFBO = GetUserBoundDrawFBO();
GLuint boundReadFBO = GetUserBoundReadFBO();
GLint viewport[4];
const bool useDepthStencil =
!mIsGLES2 || IsExtensionSupported(OES_packed_depth_stencil);
// save a few things for later restoring
curBoundFramebufferDraw = GetUserBoundDrawFBO();
curBoundFramebufferRead = GetUserBoundReadFBO();
fGetIntegerv(LOCAL_GL_RENDERBUFFER_BINDING, (GLint*) &curBoundRenderbuffer);
fGetIntegerv(LOCAL_GL_TEXTURE_BINDING_2D, (GLint*) &curBoundTexture);
fGetIntegerv(LOCAL_GL_VIEWPORT, viewport);
// the context format of what we're defining
// This becomes mActualFormat on success
ContextFormat cf(mCreationFormat);
// Create everything we need for the resize, so if it fails, we haven't broken anything
// If successful, these new resized objects will replace their associated member vars in GLContext
GLuint newOffscreenDrawFBO = 0;
GLuint newOffscreenReadFBO = 0;
GLuint newOffscreenTexture = 0;
GLuint newOffscreenColorRB = 0;
GLuint newOffscreenDepthRB = 0;
GLuint newOffscreenStencilRB = 0;
// Create the buffers and texture
if (aUseReadFBO) {
fGenFramebuffers(1, &newOffscreenReadFBO);
fGenTextures(1, &newOffscreenTexture);
}
if (useDrawMSFBO) {
fGenFramebuffers(1, &newOffscreenDrawFBO);
fGenRenderbuffers(1, &newOffscreenColorRB);
} else {
newOffscreenDrawFBO = newOffscreenReadFBO;
}
if (depth && stencil && useDepthStencil) {
fGenRenderbuffers(1, &newOffscreenDepthRB);
} else {
if (depth) {
fGenRenderbuffers(1, &newOffscreenDepthRB);
}
if (stencil) {
fGenRenderbuffers(1, &newOffscreenStencilRB);
}
}
// Allocate texture
if (aUseReadFBO) {
fBindTexture(LOCAL_GL_TEXTURE_2D, newOffscreenTexture);
fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MIN_FILTER, LOCAL_GL_LINEAR);
fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MAG_FILTER, LOCAL_GL_LINEAR);
fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_S, LOCAL_GL_CLAMP_TO_EDGE);
fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_T, LOCAL_GL_CLAMP_TO_EDGE);
if (alpha) {
fTexImage2D(LOCAL_GL_TEXTURE_2D,
0,
LOCAL_GL_RGBA,
aSize.width, aSize.height,
0,
LOCAL_GL_RGBA,
LOCAL_GL_UNSIGNED_BYTE,
NULL);
cf.red = cf.green = cf.blue = cf.alpha = 8;
} else {
fTexImage2D(LOCAL_GL_TEXTURE_2D,
0,
LOCAL_GL_RGB,
aSize.width, aSize.height,
0,
LOCAL_GL_RGB,
#ifdef XP_WIN
LOCAL_GL_UNSIGNED_BYTE,
#else
mIsGLES2 ? LOCAL_GL_UNSIGNED_SHORT_5_6_5
: LOCAL_GL_UNSIGNED_BYTE,
#endif
NULL);
#ifdef XP_WIN
cf.red = cf.green = cf.blue = 8;
#else
cf.red = 5;
cf.green = 6;
cf.blue = 5;
#endif
cf.alpha = 0;
}
}
cf.samples = samples;
// Allocate color buffer
if (useDrawMSFBO) {
GLenum colorFormat;
if (!mIsGLES2 || IsExtensionSupported(OES_rgb8_rgba8))
colorFormat = alpha ? LOCAL_GL_RGBA8 : LOCAL_GL_RGB8;
else
colorFormat = alpha ? LOCAL_GL_RGBA4 : LOCAL_GL_RGB565;
fBindRenderbuffer(LOCAL_GL_RENDERBUFFER, newOffscreenColorRB);
fRenderbufferStorageMultisample(LOCAL_GL_RENDERBUFFER,
samples,
colorFormat,
aSize.width, aSize.height);
}
// Allocate depth and stencil buffers
if (depth && stencil && useDepthStencil) {
fBindRenderbuffer(LOCAL_GL_RENDERBUFFER, newOffscreenDepthRB);
if (useDrawMSFBO) {
fRenderbufferStorageMultisample(LOCAL_GL_RENDERBUFFER,
samples,
LOCAL_GL_DEPTH24_STENCIL8,
aSize.width, aSize.height);
} else {
fRenderbufferStorage(LOCAL_GL_RENDERBUFFER,
LOCAL_GL_DEPTH24_STENCIL8,
aSize.width, aSize.height);
}
cf.depth = 24;
cf.stencil = 8;
} else {
if (depth) {
GLenum depthType;
if (mIsGLES2) {
if (IsExtensionSupported(OES_depth32)) {
depthType = LOCAL_GL_DEPTH_COMPONENT32;
cf.depth = 32;
} else if (IsExtensionSupported(OES_depth24)) {
depthType = LOCAL_GL_DEPTH_COMPONENT24;
cf.depth = 24;
} else {
depthType = LOCAL_GL_DEPTH_COMPONENT16;
cf.depth = 16;
}
} else {
depthType = LOCAL_GL_DEPTH_COMPONENT24;
cf.depth = 24;
}
fBindRenderbuffer(LOCAL_GL_RENDERBUFFER, newOffscreenDepthRB);
if (useDrawMSFBO) {
fRenderbufferStorageMultisample(LOCAL_GL_RENDERBUFFER,
samples,
depthType,
aSize.width, aSize.height);
} else {
fRenderbufferStorage(LOCAL_GL_RENDERBUFFER,
depthType,
aSize.width, aSize.height);
}
}
if (stencil) {
fBindRenderbuffer(LOCAL_GL_RENDERBUFFER, newOffscreenStencilRB);
if (useDrawMSFBO) {
fRenderbufferStorageMultisample(LOCAL_GL_RENDERBUFFER,
samples,
LOCAL_GL_STENCIL_INDEX8,
aSize.width, aSize.height);
} else {
fRenderbufferStorage(LOCAL_GL_RENDERBUFFER,
LOCAL_GL_STENCIL_INDEX8,
aSize.width, aSize.height);
}
cf.stencil = 8;
}
}
// Now assemble the FBO
BindInternalFBO(newOffscreenDrawFBO); // If we're not using a separate draw FBO, this will be the read FBO
if (useDrawMSFBO) {
fFramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER,
LOCAL_GL_COLOR_ATTACHMENT0,
LOCAL_GL_RENDERBUFFER,
newOffscreenColorRB);
}
if (depth && stencil && useDepthStencil) {
fFramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER,
LOCAL_GL_DEPTH_ATTACHMENT,
LOCAL_GL_RENDERBUFFER,
newOffscreenDepthRB);
fFramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER,
LOCAL_GL_STENCIL_ATTACHMENT,
LOCAL_GL_RENDERBUFFER,
newOffscreenDepthRB);
} else {
if (depth) {
fFramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER,
LOCAL_GL_DEPTH_ATTACHMENT,
LOCAL_GL_RENDERBUFFER,
newOffscreenDepthRB);
}
if (stencil) {
fFramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER,
LOCAL_GL_STENCIL_ATTACHMENT,
LOCAL_GL_RENDERBUFFER,
newOffscreenStencilRB);
}
}
if (aUseReadFBO) {
BindInternalFBO(newOffscreenReadFBO);
if (texture) {
fGenFramebuffers(1, &readFBO);
BindInternalFBO(readFBO);
fFramebufferTexture2D(LOCAL_GL_FRAMEBUFFER,
LOCAL_GL_COLOR_ATTACHMENT0,
LOCAL_GL_TEXTURE_2D,
newOffscreenTexture,
texture,
0);
}
if (colorMSRB) {
fGenFramebuffers(1, &drawFBO);
BindInternalFBO(drawFBO);
fFramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER,
LOCAL_GL_COLOR_ATTACHMENT0,
LOCAL_GL_RENDERBUFFER,
colorMSRB);
} else {
drawFBO = readFBO;
// drawFBO==readFBO is already bound from the 'if (texture)' block.
}
if (depthRB) {
fFramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER,
LOCAL_GL_DEPTH_ATTACHMENT,
LOCAL_GL_RENDERBUFFER,
depthRB);
}
if (stencilRB) {
fFramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER,
LOCAL_GL_STENCIL_ATTACHMENT,
LOCAL_GL_RENDERBUFFER,
stencilRB);
}
// We should be all resized. Check for framebuffer completeness.
GLenum status;
bool framebuffersComplete = true;
bool isComplete = true;
BindInternalFBO(newOffscreenDrawFBO);
BindInternalFBO(drawFBO);
status = fCheckFramebufferStatus(LOCAL_GL_FRAMEBUFFER);
if (status != LOCAL_GL_FRAMEBUFFER_COMPLETE) {
NS_WARNING("DrawFBO: Incomplete");
#ifdef DEBUG
#ifdef DEBUG
printf_stderr("Framebuffer status: %X\n", status);
#endif
framebuffersComplete = false;
#endif
isComplete = false;
}
BindInternalFBO(newOffscreenReadFBO);
BindInternalFBO(readFBO);
status = fCheckFramebufferStatus(LOCAL_GL_FRAMEBUFFER);
if (status != LOCAL_GL_FRAMEBUFFER_COMPLETE) {
NS_WARNING("ReadFBO: Incomplete");
#ifdef DEBUG
#ifdef DEBUG
printf_stderr("Framebuffer status: %X\n", status);
#endif
framebuffersComplete = false;
#endif
isComplete = false;
}
if (!framebuffersComplete) {
NS_WARNING("Error resizing offscreen framebuffer -- framebuffer(s) not complete");
BindUserDrawFBO(boundDrawFBO);
BindUserReadFBO(boundReadFBO);
// Clean up the mess
fDeleteFramebuffers(1, &newOffscreenDrawFBO);
fDeleteFramebuffers(1, &newOffscreenReadFBO);
fDeleteTextures(1, &newOffscreenTexture);
fDeleteRenderbuffers(1, &newOffscreenColorRB);
fDeleteRenderbuffers(1, &newOffscreenDepthRB);
fDeleteRenderbuffers(1, &newOffscreenStencilRB);
return isComplete;
}
BindUserDrawFBO(curBoundFramebufferDraw);
BindUserReadFBO(curBoundFramebufferRead);
fBindTexture(LOCAL_GL_TEXTURE_2D, curBoundTexture);
fBindRenderbuffer(LOCAL_GL_RENDERBUFFER, curBoundRenderbuffer);
fViewport(viewport[0], viewport[1], viewport[2], viewport[3]);
bool
GLContext::ResizeOffscreenFBOs(const ContextFormat& aCF, const gfxIntSize& aSize, const bool aNeedsReadBuffer)
{
// Early out for when we're rendering directly to the context's 'screen'.
if (!aNeedsReadBuffer && !aCF.samples)
return true;
MakeCurrent();
ContextFormat cf(aCF);
GLFormats formats = ChooseGLFormats(cf);
GLuint texture = 0;
if (aNeedsReadBuffer)
CreateTextureForOffscreen(formats, aSize, texture);
GLuint colorMSRB = 0;
GLuint depthRB = 0;
GLuint stencilRB = 0;
CreateRenderbuffersForOffscreen(formats, aSize, colorMSRB, depthRB, stencilRB);
GLuint drawFBO = 0;
GLuint readFBO = 0;
if (!AssembleOffscreenFBOs(colorMSRB, depthRB, stencilRB, texture,
drawFBO, readFBO))
{
fDeleteFramebuffers(1, &drawFBO);
fDeleteFramebuffers(1, &readFBO);
fDeleteRenderbuffers(1, &colorMSRB);
fDeleteRenderbuffers(1, &depthRB);
fDeleteRenderbuffers(1, &stencilRB);
fDeleteTextures(1, &texture);
return false;
}
// Success, so delete the old and busted
fDeleteFramebuffers(1, &mOffscreenDrawFBO);
fDeleteFramebuffers(1, &mOffscreenReadFBO);
fDeleteTextures(1, &mOffscreenTexture);
fDeleteRenderbuffers(1, &mOffscreenColorRB);
fDeleteRenderbuffers(1, &mOffscreenDepthRB);
fDeleteRenderbuffers(1, &mOffscreenStencilRB);
// Update currently bound references if we're changing what they were point to
// This way we don't rebind to old buffers when we're done here
if (curBoundFramebufferDraw == mOffscreenDrawFBO)
curBoundFramebufferDraw = newOffscreenDrawFBO;
if (curBoundFramebufferRead == mOffscreenReadFBO)
curBoundFramebufferRead = newOffscreenReadFBO;
if (curBoundTexture == mOffscreenTexture)
curBoundTexture = newOffscreenTexture;
if (curBoundRenderbuffer == mOffscreenColorRB)
curBoundRenderbuffer = newOffscreenColorRB;
else if (curBoundRenderbuffer == mOffscreenDepthRB)
curBoundRenderbuffer = newOffscreenDepthRB;
else if (curBoundRenderbuffer == mOffscreenStencilRB)
curBoundRenderbuffer = newOffscreenStencilRB;
// Success, so switch everything out.
// Store current user FBO bindings.
GLuint boundDrawFBO = GetUserBoundDrawFBO();
GLuint boundReadFBO = GetUserBoundReadFBO();
// Replace with the new hotness
mOffscreenDrawFBO = newOffscreenDrawFBO;
mOffscreenReadFBO = newOffscreenReadFBO;
mOffscreenTexture = newOffscreenTexture;
mOffscreenColorRB = newOffscreenColorRB;
mOffscreenDepthRB = newOffscreenDepthRB;
mOffscreenStencilRB = newOffscreenStencilRB;
std::swap(mOffscreenDrawFBO, drawFBO);
std::swap(mOffscreenReadFBO, readFBO);
std::swap(mOffscreenColorRB, colorMSRB);
std::swap(mOffscreenDepthRB, depthRB);
std::swap(mOffscreenStencilRB, stencilRB);
std::swap(mOffscreenTexture, texture);
// Delete the old and busted
fDeleteFramebuffers(1, &drawFBO);
fDeleteFramebuffers(1, &readFBO);
fDeleteRenderbuffers(1, &colorMSRB);
fDeleteRenderbuffers(1, &depthRB);
fDeleteRenderbuffers(1, &stencilRB);
fDeleteTextures(1, &texture);
// Rebind user FBOs, in case anything changed internally.
BindUserDrawFBO(boundDrawFBO);
BindUserReadFBO(boundReadFBO);
// Newly-created buffers are...unlikely to match.
ForceDirtyFBOs();
// Finish up.
mOffscreenSize = aSize;
mOffscreenActualSize = aSize;
mActualFormat = cf;
#ifdef DEBUG
if (DebugMode()) {
printf_stderr("Resized %dx%d offscreen FBO: r: %d g: %d b: %d a: %d depth: %d stencil: %d samples: %d\n",
mOffscreenActualSize.width, mOffscreenActualSize.height,
mActualFormat.red, mActualFormat.green, mActualFormat.blue, mActualFormat.alpha,
mActualFormat.depth, mActualFormat.stencil, mActualFormat.samples);
}
#endif
// We're good, and the framebuffer is already attached.
// Now restore the GL state back to what it was before the resize took place.
// If the user was using fb 0, this will bind the offscreen framebuffer we
// just created.
BindUserDrawFBO(curBoundFramebufferDraw);
BindUserReadFBO(curBoundFramebufferRead);
fBindTexture(LOCAL_GL_TEXTURE_2D, curBoundTexture);
fBindRenderbuffer(LOCAL_GL_RENDERBUFFER, curBoundRenderbuffer);
fViewport(viewport[0], viewport[1], viewport[2], viewport[3]);
// Make sure we know that the buffers are new and thus dirty:
ForceDirtyFBOs();
return true;
}
void
GLContext::DeleteOffscreenFBO()
GLContext::DeleteOffscreenFBOs()
{
fDeleteFramebuffers(1, &mOffscreenDrawFBO);
fDeleteFramebuffers(1, &mOffscreenReadFBO);
@ -1770,7 +1744,7 @@ GLContext::MarkDestroyed()
return;
MakeCurrent();
DeleteOffscreenFBO();
DeleteOffscreenFBOs();
fDeleteProgram(mBlitProgram);
mBlitProgram = 0;

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

@ -831,7 +831,7 @@ public:
*/
virtual bool ResizeOffscreen(const gfxIntSize& aNewSize) {
if (mOffscreenDrawFBO || mOffscreenReadFBO)
return ResizeOffscreenFBO(aNewSize, mOffscreenReadFBO != 0);
return ResizeOffscreenFBOs(aNewSize, mOffscreenReadFBO != 0);
return false;
}
@ -1631,30 +1631,62 @@ protected:
// Helper to create/resize an offscreen FBO,
// for offscreen implementations that use FBOs.
// Note that it does -not- clear the resized buffers.
bool ResizeOffscreenFBO(const gfxIntSize& aSize, const bool aUseReadFBO, const bool aDisableAA);
bool ResizeOffscreenFBO(const gfxIntSize& aSize, const bool aUseReadFBO) {
if (ResizeOffscreenFBO(aSize, aUseReadFBO, false))
return true;
if (!mCreationFormat.samples) {
NS_WARNING("ResizeOffscreenFBO failed to resize non-AA context!");
bool ResizeOffscreenFBOs(const ContextFormat& aCF, const gfxIntSize& aSize, const bool aNeedsReadBuffer);
bool ResizeOffscreenFBOs(const gfxIntSize& aSize, const bool aNeedsReadBuffer) {
if (!IsOffscreenSizeAllowed(aSize))
return false;
} else {
NS_WARNING("ResizeOffscreenFBO failed to resize AA context! Falling back to no AA...");
ContextFormat format(mCreationFormat);
if (format.samples) {
// AA path
if (ResizeOffscreenFBOs(format, aSize, aNeedsReadBuffer))
return true;
NS_WARNING("ResizeOffscreenFBOs failed to resize an AA context! Falling back to no AA...");
format.samples = 0;
}
if (DebugMode()) {
printf_stderr("Requested level of multisampling is unavailable, continuing without multisampling\n");
}
if (ResizeOffscreenFBO(aSize, aUseReadFBO, true))
if (ResizeOffscreenFBOs(format, aSize, aNeedsReadBuffer))
return true;
NS_WARNING("ResizeOffscreenFBO failed to resize AA context even without AA!");
NS_WARNING("ResizeOffscreenFBOs failed to resize non-AA context!");
return false;
}
void DeleteOffscreenFBO();
struct GLFormats {
GLFormats()
: texColor(0)
, texColorType(0)
, rbColor(0)
, depthStencil(0)
, depth(0)
, stencil(0)
, samples(0)
{}
GLenum texColor;
GLenum texColorType;
GLenum rbColor;
GLenum depthStencil;
GLenum depth;
GLenum stencil;
GLsizei samples;
};
GLFormats ChooseGLFormats(ContextFormat& aCF);
void CreateTextureForOffscreen(const GLFormats& aFormats, const gfxIntSize& aSize,
GLuint& texture);
void CreateRenderbuffersForOffscreen(const GLContext::GLFormats& aFormats, const gfxIntSize& aSize,
GLuint& colorMSRB, GLuint& depthRB, GLuint& stencilRB);
bool AssembleOffscreenFBOs(const GLuint colorMSRB,
const GLuint depthRB,
const GLuint stencilRB,
const GLuint texture,
GLuint& drawFBO,
GLuint& readFBO);
void DeleteOffscreenFBOs();
GLuint mOffscreenDrawFBO;
GLuint mOffscreenReadFBO;

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

@ -289,7 +289,7 @@ GLContextCGL::ResizeOffscreen(const gfxIntSize& aNewSize)
return false;
}
if (!ResizeOffscreenFBO(aNewSize, false)) {
if (!ResizeOffscreenFBOs(aNewSize, false)) {
[pb release];
return false;
}
@ -309,7 +309,7 @@ GLContextCGL::ResizeOffscreen(const gfxIntSize& aNewSize)
return true;
}
return ResizeOffscreenFBO(aNewSize, true);
return ResizeOffscreenFBOs(aNewSize, true);
}
class TextureImageCGL : public BasicTextureImage
@ -601,7 +601,7 @@ GLContextProviderCGL::CreateOffscreen(const gfxIntSize& aSize,
glContext = CreateOffscreenPBufferContext(aSize, actualFormat);
if (glContext &&
glContext->Init() &&
glContext->ResizeOffscreenFBO(aSize, false))
glContext->ResizeOffscreenFBOs(aSize, false))
{
glContext->mOffscreenSize = aSize;
glContext->mOffscreenActualSize = aSize;
@ -614,7 +614,7 @@ GLContextProviderCGL::CreateOffscreen(const gfxIntSize& aSize,
glContext = CreateOffscreenFBOContext(actualFormat);
if (glContext &&
glContext->Init() &&
glContext->ResizeOffscreenFBO(aSize, true))
glContext->ResizeOffscreenFBOs(aSize, true))
{
return glContext.forget();
}

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

@ -724,7 +724,7 @@ GLContextEGL::ResizeOffscreen(const gfxIntSize& aNewSize)
return false;
}
if (!ResizeOffscreenFBO(pbsize, false))
if (!ResizeOffscreenFBOs(pbsize, false))
return false;
SetOffscreenSize(aNewSize, pbsize);
@ -771,7 +771,7 @@ GLContextEGL::ResizeOffscreen(const gfxIntSize& aNewSize)
if (!config) {
return false;
}
if (!ResizeOffscreenFBO(aNewSize, true))
if (!ResizeOffscreenFBOs(aNewSize, true))
return false;
mThebesSurface = xsurface;
@ -782,12 +782,12 @@ GLContextEGL::ResizeOffscreen(const gfxIntSize& aNewSize)
#if defined(MOZ_X11) && defined(MOZ_EGL_XRENDER_COMPOSITE)
if (ResizeOffscreenPixmapSurface(aNewSize)) {
if (ResizeOffscreenFBO(aNewSize, true))
if (ResizeOffscreenFBOs(aNewSize, true))
return true;
}
#endif
return ResizeOffscreenFBO(aNewSize, true);
return ResizeOffscreenFBOs(aNewSize, true);
}
@ -1964,7 +1964,7 @@ GLContextProviderEGL::CreateOffscreen(const gfxIntSize& aSize,
return nsnull;
gfxIntSize fboSize = usePBuffers ? glContext->OffscreenActualSize() : aSize;
if (!(aFlags & GLContext::ContextFlagsGlobal) && !glContext->ResizeOffscreenFBO(fboSize, !usePBuffers))
if (!(aFlags & GLContext::ContextFlagsGlobal) && !glContext->ResizeOffscreenFBOs(fboSize, !usePBuffers))
return nsnull;
return glContext.forget();
@ -1975,7 +1975,7 @@ GLContextProviderEGL::CreateOffscreen(const gfxIntSize& aSize,
if (!glContext)
return nsnull;
if (!(aFlags & GLContext::ContextFlagsGlobal) && !glContext->ResizeOffscreenFBO(glContext->OffscreenActualSize(), true))
if (!(aFlags & GLContext::ContextFlagsGlobal) && !glContext->ResizeOffscreenFBOs(glContext->OffscreenActualSize(), true))
return nsnull;
return glContext.forget();
@ -1987,7 +1987,7 @@ GLContextProviderEGL::CreateOffscreen(const gfxIntSize& aSize,
return nsnull;
}
if (!(aFlags & GLContext::ContextFlagsGlobal) && !gUseBackingSurface && !glContext->ResizeOffscreenFBO(glContext->OffscreenActualSize(), true)) {
if (!(aFlags & GLContext::ContextFlagsGlobal) && !gUseBackingSurface && !glContext->ResizeOffscreenFBOs(glContext->OffscreenActualSize(), true)) {
// we weren't able to create the initial
// offscreen FBO, so this is dead
return nsnull;

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

@ -1307,7 +1307,7 @@ GLContextProviderGLX::CreateOffscreen(const gfxIntSize& aSize,
return nsnull;
}
if (!glContext->ResizeOffscreenFBO(aSize, true)) {
if (!glContext->ResizeOffscreenFBOs(aSize, true)) {
// we weren't able to create the initial
// offscreen FBO, so this is dead
return nsnull;

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

@ -524,10 +524,10 @@ GLContextWGL::ResizeOffscreen(const gfxIntSize& aNewSize)
MakeCurrent();
ClearSafely();
return ResizeOffscreenFBO(aNewSize, false);
return ResizeOffscreenFBOs(aNewSize, false);
}
return ResizeOffscreenFBO(aNewSize, true);
return ResizeOffscreenFBOs(aNewSize, true);
}
static GLContextWGL *
@ -782,7 +782,7 @@ GLContextProviderWGL::CreateOffscreen(const gfxIntSize& aSize,
return nsnull;
}
if (!glContext->ResizeOffscreenFBO(aSize, !glContext->mPBuffer))
if (!glContext->ResizeOffscreenFBOs(aSize, !glContext->mPBuffer))
return nsnull;
glContext->mOffscreenSize = aSize;

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

@ -110,6 +110,7 @@ public:
, mViewportScrollOffset(0, 0)
, mScrollId(NULL_SCROLL_ID)
, mCSSContentSize(0, 0)
, mResolution(1, 1)
{}
// Default copy ctor and operator= are fine
@ -151,6 +152,10 @@ public:
// Consumers often want to know the size before scaling to pixels
// so we record this size as well.
gfx::Size mCSSContentSize;
// This represents the resolution at which the associated layer
// will been rendered.
gfxSize mResolution;
};
#define MOZ_LAYER_DECL_NAME(n, e) \

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

@ -86,6 +86,7 @@ CPPSRCS = \
LayerManagerOGL.cpp \
ThebesLayerOGL.cpp \
TiledThebesLayerOGL.cpp \
ReusableTileStoreOGL.cpp \
LayerSorter.cpp \
ImageLayers.cpp \
$(NULL)

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

@ -87,8 +87,20 @@ public:
// (x*GetTileLength(), y*GetTileLength(), GetTileLength(), GetTileLength())
Tile GetTile(int x, int y) const;
// This operates the same as GetTile(aTileOrigin), but will also replace the
// specified tile with the placeholder tile. This does not call ReleaseTile
// on the removed tile.
bool RemoveTile(const nsIntPoint& aTileOrigin, Tile& aRemovedTile);
// This operates the same as GetTile(x, y), but will also replace the
// specified tile with the placeholder tile. This does not call ReleaseTile
// on the removed tile.
bool RemoveTile(int x, int y, Tile& aRemovedTile);
uint16_t GetTileLength() const { return TILEDLAYERBUFFER_TILE_SIZE; }
unsigned int GetTileCount() const { return mRetainedTiles.Length(); }
const nsIntRegion& GetValidRegion() const { return mValidRegion; }
const nsIntRegion& GetLastPaintRegion() const { return mLastPaintRegion; }
void SetLastPaintRegion(const nsIntRegion& aLastPaintRegion) {
@ -161,6 +173,30 @@ TiledLayerBuffer<Derived, Tile>::GetTile(int x, int y) const
return mRetainedTiles.SafeElementAt(index, AsDerived().GetPlaceholderTile());
}
template<typename Derived, typename Tile> bool
TiledLayerBuffer<Derived, Tile>::RemoveTile(const nsIntPoint& aTileOrigin,
Tile& aRemovedTile)
{
int firstTileX = mValidRegion.GetBounds().x / GetTileLength();
int firstTileY = mValidRegion.GetBounds().y / GetTileLength();
return RemoveTile(aTileOrigin.x / GetTileLength() - firstTileX,
aTileOrigin.y / GetTileLength() - firstTileY,
aRemovedTile);
}
template<typename Derived, typename Tile> bool
TiledLayerBuffer<Derived, Tile>::RemoveTile(int x, int y, Tile& aRemovedTile)
{
int index = x * mRetainedHeight + y;
const Tile& tileToRemove = mRetainedTiles.SafeElementAt(index, AsDerived().GetPlaceholderTile());
if (!IsPlaceholder(tileToRemove)) {
aRemovedTile = tileToRemove;
mRetainedTiles[index] = AsDerived().GetPlaceholderTile();
return true;
}
return false;
}
template<typename Derived, typename Tile> void
TiledLayerBuffer<Derived, Tile>::Update(const nsIntRegion& aNewValidRegion,
const nsIntRegion& aPaintRegion)
@ -209,14 +245,16 @@ TiledLayerBuffer<Derived, Tile>::Update(const nsIntRegion& aNewValidRegion,
int tileY = (y - oldBufferOrigin.y) / GetTileLength();
int index = tileX * oldRetainedHeight + tileY;
NS_ABORT_IF_FALSE(!IsPlaceholder(oldRetainedTiles.
SafeElementAt(index, AsDerived().GetPlaceholderTile())),
"Expected tile");
// The tile may have been removed, skip over it in this case.
if (IsPlaceholder(oldRetainedTiles.
SafeElementAt(index, AsDerived().GetPlaceholderTile()))) {
newRetainedTiles.AppendElement(AsDerived().GetPlaceholderTile());
} else {
Tile tileWithPartialValidContent = oldRetainedTiles[index];
newRetainedTiles.AppendElement(tileWithPartialValidContent);
oldRetainedTiles[index] = AsDerived().GetPlaceholderTile();
}
Tile tileWithPartialValidContent = oldRetainedTiles[index];
newRetainedTiles.AppendElement(tileWithPartialValidContent);
oldRetainedTiles[index] = AsDerived().GetPlaceholderTile();
} else {
// This tile is either:
// 1) Outside the new valid region and will simply be an empty

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

@ -353,6 +353,8 @@ ThebesLayerD3D10::VerifyContentType(SurfaceMode aMode)
NS_WARNING("Failed to create drawtarget for ThebesLayerD3D10.");
return;
}
mValidRegion.SetEmpty();
}
}

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

@ -73,6 +73,7 @@ struct ParamTraits<mozilla::layers::FrameMetrics>
WriteParam(aMsg, aParam.mViewportScrollOffset);
WriteParam(aMsg, aParam.mDisplayPort);
WriteParam(aMsg, aParam.mScrollId);
WriteParam(aMsg, aParam.mResolution);
}
static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
@ -82,7 +83,8 @@ struct ParamTraits<mozilla::layers::FrameMetrics>
ReadParam(aMsg, aIter, &aResult->mContentSize) &&
ReadParam(aMsg, aIter, &aResult->mViewportScrollOffset) &&
ReadParam(aMsg, aIter, &aResult->mDisplayPort) &&
ReadParam(aMsg, aIter, &aResult->mScrollId));
ReadParam(aMsg, aIter, &aResult->mScrollId) &&
ReadParam(aMsg, aIter, &aResult->mResolution));
}
};

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

@ -0,0 +1,188 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "ReusableTileStoreOGL.h"
namespace mozilla {
namespace layers {
ReusableTileStoreOGL::~ReusableTileStoreOGL()
{
if (mTiles.Length() == 0)
return;
mContext->MakeCurrent();
for (int i = 0; i < mTiles.Length(); i++)
mContext->fDeleteTextures(1, &mTiles[i]->mTexture.mTextureHandle);
mTiles.Clear();
}
void
ReusableTileStoreOGL::HarvestTiles(TiledLayerBufferOGL* aVideoMemoryTiledBuffer,
const nsIntRegion& aOldValidRegion,
const nsIntRegion& aNewValidRegion,
const gfxSize& aOldResolution,
const gfxSize& aNewResolution)
{
gfxSize scaleFactor = gfxSize(aNewResolution.width / aOldResolution.width,
aNewResolution.height / aOldResolution.height);
#ifdef GFX_TILEDLAYER_PREF_WARNINGS
printf_stderr("Seeing if there are any tiles we can reuse\n");
#endif
// Iterate over existing harvested tiles and release any that are contained
// within the new valid region.
mContext->MakeCurrent();
for (int i = 0; i < mTiles.Length();) {
ReusableTiledTextureOGL* tile = mTiles[i];
bool release = false;
if (tile->mResolution == aNewResolution) {
if (aNewValidRegion.Contains(tile->mTileRegion))
release = true;
} else {
nsIntRegion transformedTileRegion(tile->mTileRegion);
transformedTileRegion.ScaleRoundOut(tile->mResolution.width / aNewResolution.width,
tile->mResolution.height / aNewResolution.height);
if (aNewValidRegion.Contains(transformedTileRegion))
release = true;
}
if (release) {
#ifdef GFX_TILEDLAYER_PREF_WARNINGS
nsIntRect tileBounds = tile->mTileRegion.GetBounds();
printf_stderr("Releasing obsolete reused tile at %d,%d, x%f\n",
tileBounds.x, tileBounds.y, tile->mResolution.width);
#endif
mContext->fDeleteTextures(1, &tile->mTexture.mTextureHandle);
mTiles.RemoveElementAt(i);
continue;
}
i++;
}
// Iterate over the tiles and decide which ones we're going to harvest.
// We harvest any tile that is entirely outside of the new valid region, or
// any tile that is partially outside of the valid region and whose
// resolution has changed.
// XXX Tile iteration needs to be abstracted, or have some utility functions
// to make it simpler.
uint16_t tileSize = aVideoMemoryTiledBuffer->GetTileLength();
nsIntRect validBounds = aOldValidRegion.GetBounds();
for (int x = validBounds.x; x < validBounds.XMost();) {
int w = tileSize - x % tileSize;
if (x + w > validBounds.x + validBounds.width)
w = validBounds.x + validBounds.width - x;
for (int y = validBounds.y; y < validBounds.YMost();) {
int h = tileSize - y % tileSize;
if (y + h > validBounds.y + validBounds.height)
h = validBounds.y + validBounds.height - y;
// If the new valid region doesn't contain this tile region,
// harvest the tile.
nsIntRegion tileRegion;
tileRegion.And(aOldValidRegion, nsIntRect(x, y, w, h));
nsIntRegion intersectingRegion;
bool retainTile = false;
if (aNewResolution != aOldResolution) {
// Reconcile resolution changes.
// If the resolution changes, we know the backing layer will have been
// invalidated, so retain tiles that are partially encompassed by the
// new valid area, instead of just tiles that don't intersect at all.
nsIntRegion transformedTileRegion(tileRegion);
transformedTileRegion.ScaleRoundOut(scaleFactor.width, scaleFactor.height);
if (!aNewValidRegion.Contains(transformedTileRegion))
retainTile = true;
} else if (intersectingRegion.And(tileRegion, aNewValidRegion).IsEmpty()) {
retainTile = true;
}
if (retainTile) {
#ifdef GFX_TILEDLAYER_PREF_WARNINGS
printf_stderr("Retaining tile at %d,%d, x%f for reuse\n", x, y, aOldResolution.width);
#endif
TiledTexture removedTile;
if (aVideoMemoryTiledBuffer->RemoveTile(nsIntPoint(x, y), removedTile)) {
ReusableTiledTextureOGL* reusedTile =
new ReusableTiledTextureOGL(removedTile, tileRegion, tileSize,
aOldResolution);
mTiles.AppendElement(reusedTile);
}
#ifdef GFX_TILEDLAYER_PREF_WARNINGS
else
printf_stderr("Failed to retain tile for reuse\n");
#endif
}
y += h;
}
x += w;
}
// Now prune our reused tile store of its oldest tiles if it gets too large.
while (mTiles.Length() > aVideoMemoryTiledBuffer->GetTileCount() * mSizeLimit) {
#ifdef GFX_TILEDLAYER_PREF_WARNINGS
nsIntRect tileBounds = mTiles[0]->mTileRegion.GetBounds();
printf_stderr("Releasing old reused tile at %d,%d, x%f\n",
tileBounds.x, tileBounds.y, mTiles[0]->mResolution.width);
#endif
mContext->fDeleteTextures(1, &mTiles[0]->mTexture.mTextureHandle);
mTiles.RemoveElementAt(0);
}
#ifdef GFX_TILEDLAYER_PREF_WARNINGS
printf_stderr("Retained %d tiles\n", mTiles.Length());
#endif
}
void
ReusableTileStoreOGL::DrawTiles(TiledThebesLayerOGL* aLayer,
const nsIntRegion& aValidRegion,
const gfxSize& aResolution,
const gfx3DMatrix& aTransform,
const nsIntPoint& aRenderOffset)
{
// Render old tiles to fill in gaps we haven't had the time to render yet.
for (size_t i = 0; i < mTiles.Length(); i++) {
ReusableTiledTextureOGL* tile = mTiles[i];
// Work out the scaling factor in case of resolution differences.
gfxSize scaleFactor = gfxSize(aResolution.width / tile->mResolution.width,
aResolution.height / tile->mResolution.height);
// Get the valid tile region, in the given coordinate space.
nsIntRegion transformedTileRegion(tile->mTileRegion);
if (aResolution != tile->mResolution)
transformedTileRegion.ScaleRoundOut(scaleFactor.width, scaleFactor.height);
// Skip drawing tiles that will be completely drawn over.
if (aValidRegion.Contains(transformedTileRegion))
continue;
// Reconcile the resolution difference by adjusting the transform.
gfx3DMatrix transform = aTransform;
if (aResolution != tile->mResolution)
transform.Scale(scaleFactor.width, scaleFactor.height, 1);
// XXX We should clip here to make sure we don't overlap with the valid
// region, otherwise we may end up with rendering artifacts on
// semi-transparent layers.
// Similarly, if we have multiple tiles covering the same area, we will
// end up with rendering artifacts if the aLayer isn't opaque.
nsIntRect tileRect = tile->mTileRegion.GetBounds();
uint16_t tileStartX = tileRect.x % tile->mTileSize;
uint16_t tileStartY = tileRect.y % tile->mTileSize;
nsIntRect textureRect(tileStartX, tileStartY, tileRect.width, tileRect.height);
nsIntSize textureSize(tile->mTileSize, tile->mTileSize);
aLayer->RenderTile(tile->mTexture, transform, aRenderOffset, tileRect, textureRect, textureSize);
}
}
} // mozilla
} // layers

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

@ -0,0 +1,96 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef GFX_REUSABLETILESTOREOGL_H
#define GFX_REUSABLETILESTOREOGL_H
#include "TiledThebesLayerOGL.h"
#include "nsTArray.h"
#include "nsAutoPtr.h"
namespace mozilla {
namespace gl {
class GLContext;
}
namespace layers {
// A storage class for the information required to render a single tile from
// a TiledLayerBufferOGL.
class ReusableTiledTextureOGL
{
public:
ReusableTiledTextureOGL(TiledTexture aTexture,
const nsIntRegion& aTileRegion,
uint16_t aTileSize,
gfxSize aResolution)
: mTexture(aTexture)
, mTileRegion(aTileRegion)
, mTileSize(aTileSize)
, mResolution(aResolution)
{}
~ReusableTiledTextureOGL() {}
TiledTexture mTexture;
const nsIntRegion mTileRegion;
uint16_t mTileSize;
gfxSize mResolution;
};
// This class will operate on a TiledLayerBufferOGL to harvest tiles that have
// rendered content that is about to become invalid. We do this so that in the
// situation that we need to render an area of a TiledThebesLayerOGL that hasn't
// been updated quickly enough, we can still display something (and hopefully
// it'll be the same as the valid rendered content). While this may end up
// showing invalid data, it should only be momentarily.
class ReusableTileStoreOGL
{
public:
ReusableTileStoreOGL(gl::GLContext* aContext, float aSizeLimit)
: mContext(aContext)
, mSizeLimit(aSizeLimit)
{}
~ReusableTileStoreOGL();
// Harvests tiles from a TiledLayerBufferOGL that are about to become
// invalid. aOldValidRegion and aOldResolution should be the valid region
// and resolution of the data currently in aVideoMemoryTiledBuffer, and
// aNewValidRegion and aNewResolution should be the valid region and
// resolution of the data that is about to update aVideoMemoryTiledBuffer.
void HarvestTiles(TiledLayerBufferOGL* aVideoMemoryTiledBuffer,
const nsIntRegion& aOldValidRegion,
const nsIntRegion& aNewValidRegion,
const gfxSize& aOldResolution,
const gfxSize& aNewResolution);
// Draws all harvested tiles that don't intersect with the given valid region.
// Differences in resolution will be reconciled via altering the given
// transformation.
void DrawTiles(TiledThebesLayerOGL* aLayer,
const nsIntRegion& aValidRegion,
const gfxSize& aResolution,
const gfx3DMatrix& aTransform,
const nsIntPoint& aRenderOffset);
private:
// This GLContext should correspond to the one used in any TiledLayerBufferOGL
// that is passed into HarvestTiles and DrawTiles.
nsRefPtr<gl::GLContext> mContext;
// This determines the maximum number of tiles stored in this tile store,
// as a fraction of the amount of tiles stored in the TiledLayerBufferOGL
// given to HarvestTiles.
float mSizeLimit;
// This stores harvested tiles, in the order in which they were harvested.
nsTArray< nsAutoPtr<ReusableTiledTextureOGL> > mTiles;
};
} // layers
} // mozilla
#endif // GFX_REUSABLETILESTOREOGL_H

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

@ -4,6 +4,7 @@
#include "mozilla/layers/PLayersChild.h"
#include "TiledThebesLayerOGL.h"
#include "ReusableTileStoreOGL.h"
#include "BasicTiledThebesLayer.h"
#include "gfxImageSurface.h"
@ -37,12 +38,15 @@ TiledLayerBufferOGL::ReleaseTile(TiledTexture aTile)
void
TiledLayerBufferOGL::Upload(const BasicTiledLayerBuffer* aMainMemoryTiledBuffer,
const nsIntRegion& aNewValidRegion,
const nsIntRegion& aInvalidateRegion)
const nsIntRegion& aInvalidateRegion,
const gfxSize& aResolution)
{
#ifdef GFX_TILEDLAYER_PREF_WARNINGS
printf_stderr("Upload %i, %i, %i, %i\n", aInvalidateRegion.GetBounds().x, aInvalidateRegion.GetBounds().y, aInvalidateRegion.GetBounds().width, aInvalidateRegion.GetBounds().height);
long start = PR_IntervalNow();
#endif
mResolution = aResolution;
mMainMemoryTiledBuffer = aMainMemoryTiledBuffer;
mContext->MakeCurrent();
Update(aNewValidRegion, aInvalidateRegion);
@ -113,6 +117,15 @@ TiledThebesLayerOGL::TiledThebesLayerOGL(LayerManagerOGL *aManager)
, mVideoMemoryTiledBuffer(aManager->gl())
{
mImplData = static_cast<LayerOGL*>(this);
// XXX Add a pref for reusable tile store size
mReusableTileStore = new ReusableTileStoreOGL(aManager->gl(), 1);
}
TiledThebesLayerOGL::~TiledThebesLayerOGL()
{
mMainMemoryTiledBuffer.ReadUnlock();
if (mReusableTileStore)
delete mReusableTileStore;
}
void
@ -121,9 +134,6 @@ TiledThebesLayerOGL::PaintedTiledLayerBuffer(const BasicTiledLayerBuffer* mTiled
mMainMemoryTiledBuffer = *mTiledBuffer;
mRegionToUpload.Or(mRegionToUpload, mMainMemoryTiledBuffer.GetLastPaintRegion());
gl()->MakeCurrent();
ProcessUploadQueue(); // TODO: Remove me; this should be unnecessary.
}
void
@ -132,7 +142,29 @@ TiledThebesLayerOGL::ProcessUploadQueue()
if (mRegionToUpload.IsEmpty())
return;
mVideoMemoryTiledBuffer.Upload(&mMainMemoryTiledBuffer, mMainMemoryTiledBuffer.GetValidRegion(), mRegionToUpload);
gfxSize resolution(1, 1);
if (mReusableTileStore) {
// Work out render resolution by multiplying the resolution of our ancestors.
// Only container layers can have frame metrics, so we start off with a
// resolution of 1, 1.
// XXX For large layer trees, it would be faster to do this once from the
// root node upwards and store the value on each layer.
for (ContainerLayer* parent = GetParent(); parent; parent = parent->GetParent()) {
const FrameMetrics& metrics = parent->GetFrameMetrics();
resolution.width *= metrics.mResolution.width;
resolution.height *= metrics.mResolution.height;
}
mReusableTileStore->HarvestTiles(&mVideoMemoryTiledBuffer,
mVideoMemoryTiledBuffer.GetValidRegion(),
mMainMemoryTiledBuffer.GetValidRegion(),
mVideoMemoryTiledBuffer.GetResolution(),
resolution);
}
mVideoMemoryTiledBuffer.Upload(&mMainMemoryTiledBuffer,
mMainMemoryTiledBuffer.GetValidRegion(),
mRegionToUpload, resolution);
mValidRegion = mVideoMemoryTiledBuffer.GetValidRegion();
mMainMemoryTiledBuffer.ReadUnlock();
@ -146,12 +178,46 @@ TiledThebesLayerOGL::ProcessUploadQueue()
}
void
TiledThebesLayerOGL::RenderTile(TiledTexture aTile,
const gfx3DMatrix& aTransform,
const nsIntPoint& aOffset,
nsIntRect aScreenRect,
nsIntRect aTextureRect,
nsIntSize aTextureBounds)
{
gl()->fBindTexture(LOCAL_GL_TEXTURE_2D, aTile.mTextureHandle);
ColorTextureLayerProgram *program;
if (aTile.mFormat == LOCAL_GL_RGB) {
program = mOGLManager->GetRGBXLayerProgram();
} else {
program = mOGLManager->GetBGRALayerProgram();
}
program->Activate();
program->SetTextureUnit(0);
program->SetLayerOpacity(GetEffectiveOpacity());
program->SetLayerTransform(aTransform);
program->SetRenderOffset(aOffset);
program->SetLayerQuadRect(aScreenRect);
mOGLManager->BindAndDrawQuadWithTextureRect(program,
aTextureRect,
aTextureBounds);
}
void
TiledThebesLayerOGL::RenderLayer(int aPreviousFrameBuffer, const nsIntPoint& aOffset)
{
gl()->MakeCurrent();
ProcessUploadQueue();
// Render old tiles to fill in gaps we haven't had the time to render yet.
if (mReusableTileStore)
mReusableTileStore->DrawTiles(this, mVideoMemoryTiledBuffer.GetValidRegion(),
mVideoMemoryTiledBuffer.GetResolution(),
GetEffectiveTransform(), aOffset);
// Render valid tiles.
const nsIntRegion& visibleRegion = GetEffectiveVisibleRegion();
const nsIntRect visibleRect = visibleRegion.GetBounds();
unsigned int rowCount = 0;
@ -173,22 +239,9 @@ TiledThebesLayerOGL::RenderLayer(int aPreviousFrameBuffer, const nsIntPoint& aOf
GetTile(nsIntPoint(mVideoMemoryTiledBuffer.RoundDownToTileEdge(x),
mVideoMemoryTiledBuffer.RoundDownToTileEdge(y)));
if (tileTexture != mVideoMemoryTiledBuffer.GetPlaceholderTile()) {
gl()->fBindTexture(LOCAL_GL_TEXTURE_2D, tileTexture.mTextureHandle);
ColorTextureLayerProgram *program;
if (tileTexture.mFormat == LOCAL_GL_RGB) {
program = mOGLManager->GetRGBXLayerProgram();
} else {
program = mOGLManager->GetBGRALayerProgram();
}
program->Activate();
program->SetTextureUnit(0);
program->SetLayerOpacity(GetEffectiveOpacity());
program->SetLayerTransform(GetEffectiveTransform());
program->SetRenderOffset(aOffset);
program->SetLayerQuadRect(nsIntRect(x,y,w,h)); // screen
mOGLManager->BindAndDrawQuadWithTextureRect(program, nsIntRect(tileStartX, tileStartY, w, h), nsIntSize(mVideoMemoryTiledBuffer.GetTileLength(), mVideoMemoryTiledBuffer.GetTileLength())); // texture bounds
uint16_t tileSize = mVideoMemoryTiledBuffer.GetTileLength();
RenderTile(tileTexture, GetEffectiveTransform(), aOffset, nsIntRect(x,y,w,h),
nsIntRect(tileStartX, tileStartY, w, h), nsIntSize(tileSize, tileSize));
}
tileY++;
y += h;

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

@ -20,6 +20,8 @@ class GLContext;
namespace layers {
class ReusableTileStoreOGL;
class TiledTexture {
public:
// Constructs a placeholder TiledTexture. See the comments above
@ -73,10 +75,13 @@ public:
void Upload(const BasicTiledLayerBuffer* aMainMemoryTiledBuffer,
const nsIntRegion& aNewValidRegion,
const nsIntRegion& aInvalidateRegion);
const nsIntRegion& aInvalidateRegion,
const gfxSize& aResolution);
TiledTexture GetPlaceholderTile() const { return TiledTexture(); }
const gfxSize& GetResolution() { return mResolution; }
protected:
TiledTexture ValidateTile(TiledTexture aTile,
const nsIntPoint& aTileRect,
@ -91,6 +96,7 @@ protected:
private:
nsRefPtr<gl::GLContext> mContext;
const BasicTiledLayerBuffer* mMainMemoryTiledBuffer;
gfxSize mResolution;
void GetFormatAndTileForImageFormat(gfxASurface::gfxImageFormat aFormat,
GLenum& aOutFormat,
@ -103,10 +109,7 @@ class TiledThebesLayerOGL : public ShadowThebesLayer,
{
public:
TiledThebesLayerOGL(LayerManagerOGL *aManager);
virtual ~TiledThebesLayerOGL()
{
mMainMemoryTiledBuffer.ReadUnlock();
}
virtual ~TiledThebesLayerOGL();
// LayerOGL impl
void Destroy() {}
@ -126,10 +129,22 @@ public:
}
void PaintedTiledLayerBuffer(const BasicTiledLayerBuffer* mTiledBuffer);
void ProcessUploadQueue();
// Renders a single given tile.
// XXX This currently takes an nsIntRect, but should actually take an
// nsIntRegion and iterate over each rectangle in the region.
void RenderTile(TiledTexture aTile,
const gfx3DMatrix& aTransform,
const nsIntPoint& aOffset,
nsIntRect aScreenRect,
nsIntRect aTextureRect,
nsIntSize aTextureBounds);
private:
nsIntRegion mRegionToUpload;
BasicTiledLayerBuffer mMainMemoryTiledBuffer;
TiledLayerBufferOGL mVideoMemoryTiledBuffer;
ReusableTileStoreOGL* mReusableTileStore;
};
} // layers

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

@ -53,6 +53,7 @@
#include "gfxColor.h"
#include "gfxMatrix.h"
#include "gfxPattern.h"
#include "gfxPoint.h"
#include "nsRect.h"
#include "nsRegion.h"
#include "gfxASurface.h"
@ -458,6 +459,27 @@ struct ParamTraits<gfxMatrix>
}
};
template<>
struct ParamTraits<gfxSize>
{
typedef gfxSize paramType;
static void Write(Message* aMsg, const paramType& aParam)
{
WriteParam(aMsg, aParam.width);
WriteParam(aMsg, aParam.height);
}
static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
{
if (ReadParam(aMsg, aIter, &aResult->width) &&
ReadParam(aMsg, aIter, &aResult->height))
return true;
return false;
}
};
template<>
struct ParamTraits<gfx3DMatrix>
{

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

@ -475,3 +475,13 @@ xpc_DumpJSObject(JSObject* obj)
return true;
}
#ifdef DEBUG
void
xpc_PrintAllReferencesTo(void *p)
{
/* p must be a JS object */
XPCJSRuntime* rt = nsXPConnect::GetRuntimeInstance();
JS_DumpHeap(rt->GetJSRuntime(), stdout, nsnull, JSTRACE_OBJECT, p, 0x7fffffff, nsnull);
}
#endif

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

@ -119,9 +119,6 @@ nsXPConnect::nsXPConnect()
mRuntime = XPCJSRuntime::newXPCJSRuntime(this);
nsCycleCollector_registerRuntime(nsIProgrammingLanguage::JAVASCRIPT, this);
#ifdef DEBUG_CC
mJSRoots.ops = nsnull;
#endif
char* reportableEnv = PR_GetEnv("MOZ_REPORT_ALL_JS_EXCEPTIONS");
if (reportableEnv && *reportableEnv)
@ -399,14 +396,14 @@ nsXPConnect::Collect(PRUint32 reason, PRUint32 kind)
// JS objects that are part of cycles the cycle collector breaks will be
// collected by the next JS.
//
// If DEBUG_CC is not defined the cycle collector will not traverse roots
// If WantAllTraces() is false the cycle collector will not traverse roots
// from category 1 or any JS objects held by them. Any JS objects they hold
// will already be marked by the JS GC and will thus be colored black
// themselves. Any C++ objects they hold will have a missing (untraversed)
// edge from the JS object to the C++ object and so it will be marked black
// too. This decreases the number of objects that the cycle collector has to
// deal with.
// To improve debugging, if DEBUG_CC is defined all JS objects are
// To improve debugging, if WantAllTraces() is true all JS objects are
// traversed.
MOZ_ASSERT(reason < js::gcreason::NUM_REASONS);
@ -431,37 +428,6 @@ nsXPConnect::GarbageCollect(PRUint32 reason, PRUint32 kind)
return NS_OK;
}
#ifdef DEBUG_CC
struct NoteJSRootTracer : public JSTracer
{
NoteJSRootTracer(PLDHashTable *aObjects,
nsCycleCollectionTraversalCallback& cb)
: mObjects(aObjects),
mCb(cb)
{
}
PLDHashTable* mObjects;
nsCycleCollectionTraversalCallback& mCb;
};
static void
NoteJSRoot(JSTracer *trc, void *thing, JSGCTraceKind kind)
{
if (AddToCCKind(kind)) {
NoteJSRootTracer *tracer = static_cast<NoteJSRootTracer*>(trc);
PLDHashEntryHdr *entry = PL_DHashTableOperate(tracer->mObjects, thing,
PL_DHASH_ADD);
if (entry && !reinterpret_cast<PLDHashEntryStub*>(entry)->key) {
reinterpret_cast<PLDHashEntryStub*>(entry)->key = thing;
tracer->mCb.NoteRoot(nsIProgrammingLanguage::JAVASCRIPT, thing,
nsXPConnect::GetXPConnect());
}
} else if (kind != JSTRACE_STRING) {
JS_TraceChildren(trc, thing, kind);
}
}
#endif
struct NoteWeakMapChildrenTracer : public JSTracer
{
NoteWeakMapChildrenTracer(nsCycleCollectionTraversalCallback &cb)
@ -538,8 +504,7 @@ TraceWeakMapping(js::WeakMapTracer *trc, JSObject *m,
}
nsresult
nsXPConnect::BeginCycleCollection(nsCycleCollectionTraversalCallback &cb,
bool explainLiveExpectedGarbage)
nsXPConnect::BeginCycleCollection(nsCycleCollectionTraversalCallback &cb)
{
// It is important not to call GetSafeJSContext while on the
// cycle-collector thread since this context will be destroyed
@ -565,31 +530,6 @@ nsXPConnect::BeginCycleCollection(nsCycleCollectionTraversalCallback &cb,
gcHasRun = true;
}
#ifdef DEBUG_CC
NS_ASSERTION(!mJSRoots.ops, "Didn't call FinishCycleCollection?");
if (explainLiveExpectedGarbage) {
// Being called from nsCycleCollector::ExplainLiveExpectedGarbage.
// Record all objects held by the JS runtime. This avoids doing a
// complete GC if we're just tracing to explain (from
// ExplainLiveExpectedGarbage), which makes the results of cycle
// collection identical for DEBUG_CC and non-DEBUG_CC builds.
if (!PL_DHashTableInit(&mJSRoots, PL_DHashGetStubOps(), nsnull,
sizeof(PLDHashEntryStub), PL_DHASH_MIN_SIZE)) {
mJSRoots.ops = nsnull;
return NS_ERROR_OUT_OF_MEMORY;
}
NoteJSRootTracer trc(&mJSRoots, cb);
JS_TracerInit(&trc, mCycleCollectionContext->GetJSContext(), NoteJSRoot);
JS_TraceRuntime(&trc);
}
#else
NS_ASSERTION(!explainLiveExpectedGarbage, "Didn't call nsXPConnect::Collect()?");
#endif
GetRuntime()->AddXPConnectRoots(cb);
NoteWeakMapsTracer trc(GetRuntime()->GetJSRuntime(), TraceWeakMapping, cb);
@ -638,19 +578,6 @@ nsXPConnect::FinishTraverse()
return NS_OK;
}
nsresult
nsXPConnect::FinishCycleCollection()
{
#ifdef DEBUG_CC
if (mJSRoots.ops) {
PL_DHashTableFinish(&mJSRoots);
mJSRoots.ops = nsnull;
}
#endif
return NS_OK;
}
nsCycleCollectionParticipant *
nsXPConnect::ToParticipant(void *p)
{
@ -665,19 +592,6 @@ nsXPConnect::Root(void *p)
return NS_OK;
}
#ifdef DEBUG_CC
void
nsXPConnect::PrintAllReferencesTo(void *p)
{
#ifdef DEBUG
XPCCallContext ccx(NATIVE_CALLER);
if (ccx.IsValid())
JS_DumpHeap(ccx.GetJSContext(), stdout, nsnull, 0, p,
0x7fffffff, nsnull);
#endif
}
#endif
NS_IMETHODIMP
nsXPConnect::Unlink(void *p)
{
@ -909,30 +823,7 @@ nsXPConnect::Traverse(void *p, nsCycleCollectionTraversalCallback &cb)
}
}
bool isMarked;
#ifdef DEBUG_CC
// Note that the conditions under which we specify GCMarked vs.
// GCUnmarked are different between ExplainLiveExpectedGarbage and
// the normal case. In the normal case, we're saying that anything
// reachable from a JS runtime root is itself such a root. This
// doesn't actually break anything; it really just does some of the
// cycle collector's work for it. However, when debugging, we
// (1) actually need to know what the root is and (2) don't want to
// do an extra GC, so we use mJSRoots, built from JS_TraceRuntime,
// which produces a different result because we didn't call
// JS_TraceChildren to trace everything that was reachable.
if (mJSRoots.ops) {
// ExplainLiveExpectedGarbage codepath
PLDHashEntryHdr* entry =
PL_DHashTableOperate(&mJSRoots, p, PL_DHASH_LOOKUP);
isMarked = markJSObject || PL_DHASH_ENTRY_IS_BUSY(entry);
} else
#endif
{
// Normal codepath (matches non-DEBUG_CC codepath).
isMarked = markJSObject || !xpc_IsGrayGCThing(p);
}
bool isMarked = markJSObject || !xpc_IsGrayGCThing(p);
if (cb.WantDebugInfo()) {
char name[72];
@ -982,8 +873,8 @@ nsXPConnect::Traverse(void *p, nsCycleCollectionTraversalCallback &cb)
// There's no need to trace objects that have already been marked by the JS
// GC. Any JS objects hanging from them will already be marked. Only do this
// if DEBUG_CC is not defined, else we do want to know about all JS objects
// to get better graphs and explanations.
// if cb.WantAllTraces() is false, otherwise we do want to know about all JS
// objects to get better graphs and explanations.
if (!cb.WantAllTraces() && isMarked)
return NS_OK;

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

@ -537,16 +537,11 @@ public:
virtual void NotifyEnterCycleCollectionThread();
virtual void NotifyLeaveCycleCollectionThread();
virtual void NotifyEnterMainThread();
virtual nsresult BeginCycleCollection(nsCycleCollectionTraversalCallback &cb,
bool explainExpectedLiveGarbage);
virtual nsresult BeginCycleCollection(nsCycleCollectionTraversalCallback &cb);
virtual nsresult FinishTraverse();
virtual nsresult FinishCycleCollection();
virtual nsCycleCollectionParticipant *ToParticipant(void *p);
virtual bool NeedCollect();
virtual void Collect(PRUint32 reason, PRUint32 kind);
#ifdef DEBUG_CC
virtual void PrintAllReferencesTo(void *p);
#endif
XPCCallContext *GetCycleCollectionContext()
{
@ -598,9 +593,6 @@ private:
// an 'after' notification without getting an 'on' notification. If we don't
// watch out for this, we'll do an unmatched |pop| on the context stack.
PRUint16 mEventDepth;
#ifdef DEBUG_CC
PLDHashTable mJSRoots;
#endif
nsAutoPtr<XPCCallContext> mCycleCollectionContext;
typedef nsBaseHashtable<nsPtrHashKey<void>, nsISupports*, nsISupports*> ScopeSet;

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

@ -250,6 +250,10 @@ static void RecordFrameMetrics(nsIFrame* aForFrame,
}
metrics.mScrollId = aScrollId;
nsIPresShell* presShell = presContext->GetPresShell();
metrics.mResolution = gfxSize(presShell->GetXResolution(), presShell->GetYResolution());
aRoot->SetFrameMetrics(metrics);
}

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

@ -78,12 +78,6 @@ function run() {
sel.removeAllRanges();
sel.modify("move", "forward", "character");
// Similarly, we should silently fail if the selection has been detached.
$("c").focus();
sel.collapse($("p1"), 0);
sel.getRangeAt(0).detach();
sel.modify("move", "forward", "character");
// Now focus our first div and put the cursor at the beginning of p1.
$("c").focus();
sel.collapse($("p1"), 0);

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

@ -52,6 +52,7 @@
#include "nsViewportFrame.h"
#include "nsSubDocumentFrame.h"
#include "nsIObserver.h"
#include "nsContentUtils.h"
typedef nsContentView::ViewConfig ViewConfig;
using namespace mozilla::layers;
@ -641,7 +642,9 @@ RenderFrameParent::AllocPLayers(LayerManager::LayersBackend* aBackendType)
*aBackendType = LayerManager::LAYERS_NONE;
return nsnull;
}
LayerManager* lm = GetLayerManager();
nsRefPtr<LayerManager> lm =
nsContentUtils::LayerManagerForDocument(mFrameLoader->OwnerDoc());
ShadowLayerManager* slm = lm->AsShadowManager();
if (!slm) {
*aBackendType = LayerManager::LAYERS_NONE;
@ -692,13 +695,6 @@ RenderFrameParent::BuildViewMap()
mContentViews = newContentViews;
}
LayerManager*
RenderFrameParent::GetLayerManager() const
{
nsIDocument* doc = mFrameLoader->OwnerDoc();
return doc->GetShell()->GetLayerManager();
}
ShadowLayersParent*
RenderFrameParent::GetShadowLayers() const
{

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

@ -111,7 +111,6 @@ protected:
private:
void BuildViewMap();
LayerManager* GetLayerManager() const;
ShadowLayersParent* GetShadowLayers() const;
ContainerLayer* GetRootLayer() const;

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

@ -8,5 +8,5 @@
<!-- From https://bugzilla.mozilla.org/show_bug.cgi?id=368840 -->
<rect x="0%" y="0%" width="100%" height="100%" fill="black"/>
<rect x="0%" y="0%" width="100%" height="100%" fill="white"/>
</svg>

До

Ширина:  |  Высота:  |  Размер: 345 B

После

Ширина:  |  Высота:  |  Размер: 345 B

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

@ -9266,7 +9266,7 @@ CSSParserImpl::ParsePaint(nsCSSProperty aPropID)
return false;
if (x.GetUnit() == eCSSUnit_URL) {
if (!ParseVariant(y, VARIANT_COLOR | VARIANT_NONE, nsnull))
y.SetColorValue(NS_RGB(0, 0, 0));
y.SetNoneValue();
}
if (!ExpectEndProperty())
return false;

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

@ -365,7 +365,7 @@ pref("places.frecency.unvisitedTypedBonus", 200);
pref("gfx.color_management.mode", 0);
#ifdef ANDROID
// 0=fixed margin, 1=velocity bias, 2=dynamic resolution, 3=no margins
// 0=fixed margin, 1=velocity bias, 2=dynamic resolution, 3=no margins, 4=prediction bias
pref("gfx.displayport.strategy", 1);
// all of the following displayport strategy prefs will be divided by 1000
// to obtain some multiplier which is then used in the strategy.
@ -375,12 +375,14 @@ pref("gfx.displayport.strategy_fm.danger_x", -1); // danger zone on x-axis when
pref("gfx.displayport.strategy_fm.danger_y", -1); // danger zone on y-axis when multiplied by viewport height
// velocity bias strategy options
pref("gfx.displayport.strategy_vb.multiplier", -1); // displayport dimension multiplier
pref("gfx.displayport.strategy_vb.threshold", -1); // velocity threshold in pixels/frame when multiplied by screen DPI
pref("gfx.displayport.strategy_vb.threshold", -1); // velocity threshold in inches/frame
pref("gfx.displayport.strategy_vb.reverse_buffer", -1); // fraction of buffer to keep in reverse direction from scroll
pref("gfx.displayport.strategy_vb.danger_x_base", -1); // danger zone on x-axis when multiplied by viewport width
pref("gfx.displayport.strategy_vb.danger_y_base", -1); // danger zone on y-axis when multiplied by viewport height
pref("gfx.displayport.strategy_vb.danger_x_incr", -1); // additional danger zone on x-axis when multiplied by viewport width and velocity
pref("gfx.displayport.strategy_vb.danger_y_incr", -1); // additional danger zone on y-axis when multiplied by viewport height and velocity
// prediction bias strategy options
pref("gfx.displayport.strategy_pb.threshold", -1); // velocity threshold in inches/frame
#endif
// don't allow JS to move and resize existing windows

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

@ -124,6 +124,7 @@ FENNEC_JAVA_FILES = \
gfx/CheckerboardImage.java \
gfx/DisplayPortCalculator.java \
gfx/DisplayPortMetrics.java \
gfx/DrawTimingQueue.java \
gfx/FloatSize.java \
gfx/GeckoLayerClient.java \
gfx/GLController.java \

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

@ -32,6 +32,7 @@ final class DisplayPortCalculator {
private static final String PREF_DISPLAYPORT_VB_DANGER_Y_BASE = "gfx.displayport.strategy_vb.danger_y_base";
private static final String PREF_DISPLAYPORT_VB_DANGER_X_INCR = "gfx.displayport.strategy_vb.danger_x_incr";
private static final String PREF_DISPLAYPORT_VB_DANGER_Y_INCR = "gfx.displayport.strategy_vb.danger_y_incr";
private static final String PREF_DISPLAYPORT_PB_VELOCITY_THRESHOLD = "gfx.displayport.strategy_pb.threshold";
private static DisplayPortStrategy sStrategy = new VelocityBiasStrategy(null);
@ -46,6 +47,14 @@ final class DisplayPortCalculator {
return sStrategy.aboutToCheckerboard(metrics, (velocity == null ? ZERO_VELOCITY : velocity), displayPort);
}
static boolean drawTimeUpdate(long millis, int pixels) {
return sStrategy.drawTimeUpdate(millis, pixels);
}
static void resetPageState() {
sStrategy.resetPageState();
}
static void addPrefNames(JSONArray prefs) {
prefs.put(PREF_DISPLAYPORT_STRATEGY);
prefs.put(PREF_DISPLAYPORT_FM_MULTIPLIER);
@ -58,6 +67,7 @@ final class DisplayPortCalculator {
prefs.put(PREF_DISPLAYPORT_VB_DANGER_Y_BASE);
prefs.put(PREF_DISPLAYPORT_VB_DANGER_X_INCR);
prefs.put(PREF_DISPLAYPORT_VB_DANGER_Y_INCR);
prefs.put(PREF_DISPLAYPORT_PB_VELOCITY_THRESHOLD);
}
/**
@ -84,6 +94,9 @@ final class DisplayPortCalculator {
case 3:
sStrategy = new NoMarginStrategy(prefs);
break;
case 4:
sStrategy = new PredictionBiasStrategy(prefs);
break;
default:
Log.e(LOGTAG, "Invalid strategy index specified");
return false;
@ -97,11 +110,15 @@ final class DisplayPortCalculator {
return (float)(value == null || value < 0 ? defaultValue : value) / 1000f;
}
private interface DisplayPortStrategy {
private static abstract class DisplayPortStrategy {
/** Calculates a displayport given a viewport and panning velocity. */
public DisplayPortMetrics calculate(ImmutableViewportMetrics metrics, PointF velocity);
public abstract DisplayPortMetrics calculate(ImmutableViewportMetrics metrics, PointF velocity);
/** Returns true if a checkerboard is about to be visible and we should not throttle drawing. */
public boolean aboutToCheckerboard(ImmutableViewportMetrics metrics, PointF velocity, DisplayPortMetrics displayPort);
public abstract boolean aboutToCheckerboard(ImmutableViewportMetrics metrics, PointF velocity, DisplayPortMetrics displayPort);
/** Notify the strategy of a new recorded draw time. Return false to turn off draw time recording. */
public boolean drawTimeUpdate(long millis, int pixels) { return false; }
/** Reset any page-specific state stored, as the page being displayed has changed. */
public void resetPageState() {}
}
/**
@ -194,10 +211,21 @@ final class DisplayPortCalculator {
return margins;
}
/**
* Clamp the given rect to the page bounds and return it.
*/
private static RectF clampToPageBounds(RectF rect, ImmutableViewportMetrics metrics) {
rect.left = Math.max(rect.left, 0);
rect.top = Math.max(rect.top, 0);
rect.right = Math.min(rect.right, metrics.pageSizeWidth);
rect.bottom = Math.min(rect.bottom, metrics.pageSizeHeight);
return rect;
}
/**
* This class implements the variation where we basically don't bother with a a display port.
*/
private static class NoMarginStrategy implements DisplayPortStrategy {
private static class NoMarginStrategy extends DisplayPortStrategy {
NoMarginStrategy(Map<String, Integer> prefs) {
// no prefs in this strategy
}
@ -228,7 +256,7 @@ final class DisplayPortCalculator {
* and/or (b) increasing the buffer on the other axis to compensate for the reduced buffer on
* one axis.
*/
private static class FixedMarginStrategy implements DisplayPortStrategy {
private static class FixedMarginStrategy extends DisplayPortStrategy {
// The length of each axis of the display port will be the corresponding view length
// multiplied by this factor.
private final float SIZE_MULTIPLIER;
@ -294,7 +322,7 @@ final class DisplayPortCalculator {
* so that it is almost entirely in the direction of the pan, with a little bit in the
* reverse direction.
*/
private static class VelocityBiasStrategy implements DisplayPortStrategy {
private static class VelocityBiasStrategy extends DisplayPortStrategy {
// The length of each axis of the display port will be the corresponding view length
// multiplied by this factor.
private final float SIZE_MULTIPLIER;
@ -420,7 +448,7 @@ final class DisplayPortCalculator {
* looks blurry. The assumption is that drawing extra that we never display is better than checkerboarding,
* where we draw less but never even show it on the screen.
*/
private static class DynamicResolutionStrategy implements DisplayPortStrategy {
private static class DynamicResolutionStrategy extends DisplayPortStrategy {
// The length of each axis of the display port will be the corresponding view length
// multiplied by this factor.
private static final float SIZE_MULTIPLIER = 1.5f;
@ -609,4 +637,117 @@ final class DisplayPortCalculator {
return "DynamicResolutionStrategy";
}
}
/**
* This class implements the variation where we use the draw time to predict where we will be when
* a draw completes, and draw that instead of where we are now. In this variation, when our panning
* speed drops below a certain threshold, we draw 9 viewports' worth of content so that the user can
* pan in any direction without encountering checkerboarding.
* Once the user is panning, we modify the displayport to encompass an area range of where we think
* the user will be when the draw completes. This heuristic relies on both the estimated draw time
* the panning velocity; unexpected changes in either of these values will cause the heuristic to
* fail and show checkerboard.
*/
private static class PredictionBiasStrategy extends DisplayPortStrategy {
private static float VELOCITY_THRESHOLD;
private int mPixelArea; // area of the viewport, used in draw time calculations
private int mMinFramesToDraw; // minimum number of frames we take to draw
private int mMaxFramesToDraw; // maximum number of frames we take to draw
PredictionBiasStrategy(Map<String, Integer> prefs) {
VELOCITY_THRESHOLD = GeckoAppShell.getDpi() * getFloatPref(prefs, PREF_DISPLAYPORT_PB_VELOCITY_THRESHOLD, 16);
resetPageState();
}
public DisplayPortMetrics calculate(ImmutableViewportMetrics metrics, PointF velocity) {
float width = metrics.getWidth();
float height = metrics.getHeight();
mPixelArea = (int)(width * height);
if (velocity.length() < VELOCITY_THRESHOLD) {
// if we're going slow, expand the displayport to 9x viewport size
RectF margins = new RectF(width, height, width, height);
return getTileAlignedDisplayPortMetrics(margins, metrics.zoomFactor, metrics);
}
// figure out how far we expect to be
float minDx = velocity.x * mMinFramesToDraw;
float minDy = velocity.y * mMinFramesToDraw;
float maxDx = velocity.x * mMaxFramesToDraw;
float maxDy = velocity.y * mMaxFramesToDraw;
// figure out how many pixels we will be drawing when we draw the above-calculated range.
// this will be larger than the viewport area.
float pixelsToDraw = (width + Math.abs(maxDx - minDx)) * (height + Math.abs(maxDy - minDy));
// adjust how far we will get because of the time spent drawing all these extra pixels. this
// will again increase the number of pixels drawn so really we could keep iterating this over
// and over, but once seems enough for now.
maxDx = maxDx * pixelsToDraw / mPixelArea;
maxDy = maxDy * pixelsToDraw / mPixelArea;
// and finally generate the displayport. the min/max stuff takes care of
// negative velocities as well as positive.
RectF margins = new RectF(
-Math.min(minDx, maxDx),
-Math.min(minDy, maxDy),
Math.max(minDx, maxDx),
Math.max(minDy, maxDy));
return getTileAlignedDisplayPortMetrics(margins, metrics.zoomFactor, metrics);
}
public boolean aboutToCheckerboard(ImmutableViewportMetrics metrics, PointF velocity, DisplayPortMetrics displayPort) {
// the code below is the same as in calculate() but is awkward to refactor since it has multiple outputs.
// refer to the comments in calculate() to understand what this is doing.
float minDx = velocity.x * mMinFramesToDraw;
float minDy = velocity.y * mMinFramesToDraw;
float maxDx = velocity.x * mMaxFramesToDraw;
float maxDy = velocity.y * mMaxFramesToDraw;
float pixelsToDraw = (metrics.getWidth() + Math.abs(maxDx - minDx)) * (metrics.getHeight() + Math.abs(maxDy - minDy));
maxDx = maxDx * pixelsToDraw / mPixelArea;
maxDy = maxDy * pixelsToDraw / mPixelArea;
// now that we have an idea of how far we will be when the draw completes, take the farthest
// end of that range and see if it falls outside the displayport bounds. if it does, allow
// the draw to go through
RectF predictedViewport = metrics.getViewport();
predictedViewport.left += maxDx;
predictedViewport.top += maxDy;
predictedViewport.right += maxDx;
predictedViewport.bottom += maxDy;
predictedViewport = clampToPageBounds(predictedViewport, metrics);
return !displayPort.contains(predictedViewport);
}
@Override
public boolean drawTimeUpdate(long millis, int pixels) {
// calculate the number of frames it took to draw a viewport-sized area
float normalizedTime = (float)mPixelArea * (float)millis / (float)pixels;
int normalizedFrames = (int)FloatMath.ceil(normalizedTime * 60f / 1000f);
// broaden our range on how long it takes to draw if the draw falls outside
// the range. this allows it to grow gradually. this heuristic may need to
// be tweaked into more of a floating window average or something.
if (normalizedFrames <= mMinFramesToDraw) {
mMinFramesToDraw--;
} else if (normalizedFrames > mMaxFramesToDraw) {
mMaxFramesToDraw++;
} else {
return true;
}
Log.d(LOGTAG, "Widened draw range to [" + mMinFramesToDraw + ", " + mMaxFramesToDraw + "]");
return true;
}
@Override
public void resetPageState() {
mMinFramesToDraw = 0;
mMaxFramesToDraw = 2;
}
@Override
public String toString() {
return "PredictionBiasStrategy threshold=" + VELOCITY_THRESHOLD;
}
}
}

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

@ -6,6 +6,7 @@
package org.mozilla.gecko.gfx;
import android.graphics.RectF;
import org.mozilla.gecko.FloatUtils;
/*
* This class keeps track of the area we request Gecko to paint, as well
@ -32,6 +33,11 @@ public final class DisplayPortMetrics {
return mPosition.contains(rect);
}
public boolean fuzzyEquals(DisplayPortMetrics metrics) {
return RectUtils.fuzzyEquals(mPosition, metrics.mPosition)
&& FloatUtils.fuzzyEquals(mResolution, metrics.mResolution);
}
public String toJSON() {
StringBuffer sb = new StringBuffer(256);
sb.append("{ \"left\": ").append(mPosition.left)

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

@ -0,0 +1,95 @@
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.gecko.gfx;
import android.os.SystemClock;
/**
* A custom-built data structure to assist with measuring draw times.
*
* This class maintains a fixed-size circular buffer of DisplayPortMetrics
* objects and associated timestamps. It provides only three operations, which
* is all we require for our purposes of measuring draw times. Note
* in particular that the class is designed so that even though it is
* accessed from multiple threads, it does not require synchronization;
* any concurrency errors that result from this are handled gracefully.
*
* Assuming an unrolled buffer so that mTail is greater than mHead, the data
* stored in the buffer at entries [mHead, mTail) will never be modified, and
* so are "safe" to read. If this reading is done on the same thread that
* owns mHead, then reading the range [mHead, mTail) is guaranteed to be safe
* since the range itself will not shrink.
*/
final class DrawTimingQueue {
private static final String LOGTAG = "GeckoDrawTimingQueue";
private static final int BUFFER_SIZE = 16;
private final DisplayPortMetrics[] mMetrics;
private final long[] mTimestamps;
private int mHead;
private int mTail;
DrawTimingQueue() {
mMetrics = new DisplayPortMetrics[BUFFER_SIZE];
mTimestamps = new long[BUFFER_SIZE];
mHead = BUFFER_SIZE - 1;
mTail = 0;
}
/**
* Add a new entry to the tail of the queue. If the buffer is full,
* do nothing. This must only be called from the Java UI thread.
*/
boolean add(DisplayPortMetrics metrics) {
if (mHead == mTail) {
return false;
}
mMetrics[mTail] = metrics;
mTimestamps[mTail] = SystemClock.uptimeMillis();
mTail = (mTail + 1) % BUFFER_SIZE;
return true;
}
/**
* Find the timestamp associated with the given metrics, AND remove
* all metrics objects from the start of the queue up to and including
* the one provided. Note that because of draw coalescing, the metrics
* object passed in here may not be the one at the head of the queue,
* and so we must iterate our way through the list to find it.
* This must only be called from the compositor thread.
*/
long findTimeFor(DisplayPortMetrics metrics) {
// keep a copy of the tail pointer so that we ignore new items
// added to the queue while we are searching. this is fine because
// the one we are looking for will either have been added already
// or will not be in the queue at all.
int tail = mTail;
// walk through the "safe" range from mHead to tail; these entries
// will not be modified unless we change mHead.
int i = (mHead + 1) % BUFFER_SIZE;
while (i != tail) {
if (mMetrics[i].fuzzyEquals(metrics)) {
// found it, copy out the timestamp to a local var BEFORE
// changing mHead or add could clobber the timestamp.
long timestamp = mTimestamps[i];
mHead = i;
return timestamp;
}
i = (i + 1) % BUFFER_SIZE;
}
return -1;
}
/**
* Reset the buffer to empty.
* This must only be called from the compositor thread.
*/
void reset() {
// we can only modify mHead on this thread.
mHead = (mTail + BUFFER_SIZE - 1) % BUFFER_SIZE;
}
}

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

@ -74,6 +74,9 @@ public class GeckoLayerClient implements GeckoEventResponder,
private DisplayPortMetrics mDisplayPort;
private DisplayPortMetrics mReturnDisplayPort;
private boolean mRecordDrawTimes;
private DrawTimingQueue mDrawTimingQueue;
private VirtualLayer mRootLayer;
/* The Gecko viewport as per the UI thread. Must be touched only on the UI thread. */
@ -99,6 +102,8 @@ public class GeckoLayerClient implements GeckoEventResponder,
mScreenSize = new IntSize(0, 0);
mWindowSize = new IntSize(0, 0);
mDisplayPort = new DisplayPortMetrics();
mRecordDrawTimes = true;
mDrawTimingQueue = new DrawTimingQueue();
mCurrentViewTransform = new ViewTransform(0, 0, 1);
}
@ -193,6 +198,10 @@ public class GeckoLayerClient implements GeckoEventResponder,
mDisplayPort = displayPort;
mGeckoViewport = clampedMetrics;
if (mRecordDrawTimes) {
mDrawTimingQueue.add(displayPort);
}
GeckoAppShell.sendEventToGecko(GeckoEvent.createViewportEvent(clampedMetrics, displayPort));
}
@ -342,6 +351,8 @@ public class GeckoLayerClient implements GeckoEventResponder,
mLayerController.abortPanZoomAnimation();
mLayerController.getView().setPaintState(LayerView.PAINT_BEFORE_FIRST);
}
DisplayPortCalculator.resetPageState();
mDrawTimingQueue.reset();
mLayerController.getView().getRenderer().resetCheckerboard();
GeckoAppShell.screenshotWholePage(Tabs.getInstance().getSelectedTab());
}
@ -393,6 +404,19 @@ public class GeckoLayerClient implements GeckoEventResponder,
mRootLayer.setPositionAndResolution(x, y, x + width, y + height, resolution);
if (layersUpdated && mRecordDrawTimes) {
// If we got a layers update, that means a draw finished. Check to see if the area drawn matches
// one of our requested displayports; if it does calculate the draw time and notify the
// DisplayPortCalculator
DisplayPortMetrics drawn = new DisplayPortMetrics(x, y, x + width, y + height, resolution);
long time = mDrawTimingQueue.findTimeFor(drawn);
if (time >= 0) {
long now = SystemClock.uptimeMillis();
time = now - time;
mRecordDrawTimes = DisplayPortCalculator.drawTimeUpdate(time, width * height);
}
}
if (layersUpdated && mDrawListener != null) {
/* Used by robocop for testing purposes */
mDrawListener.drawFinished();

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

@ -103,6 +103,7 @@ XPIDLSRCS = \
nsITransport.idl \
nsISocketTransport.idl \
nsISocketTransportService.idl \
nsISpeculativeConnect.idl \
nsIServerSocket.idl \
nsIResumableChannel.idl \
nsIRequestObserverProxy.idl \

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

@ -0,0 +1,69 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla.
*
* The Initial Developer of the Original Code is
* Netscape Communications.
* Portions created by the Initial Developer are Copyright (C) 2012
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Patrick McManus <mcmanus@ducksong.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsISupports.idl"
interface nsIURI;
interface nsIInterfaceRequestor;
interface nsIEventTarget;
[scriptable, uuid(b3c53863-1313-480a-90a2-5b0da651ee5e)]
interface nsISpeculativeConnect : nsISupports
{
/**
* Called as a hint to indicate a new transaction for the URI is likely coming
* soon. The implementer may use this information to start a TCP
* and/or SSL level handshake for that resource immediately so that it is
* ready and/or progressed when the transaction is actually submitted.
*
* No obligation is taken on by the implementer, nor is the submitter obligated
* to actually open the new channel.
*
* @param aURI the URI of the hinted transaction
* @param aCallbacks any security callbacks for use with SSL for interfaces
* such as nsIBadCertListener. May be null.
* @param aTarget the thread on which the release of the callbacks will
* occur. May be null for "any thread".
*
*/
void speculativeConnect(in nsIURI aURI,
in nsIInterfaceRequestor aCallbacks,
in nsIEventTarget aTarget);
};

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

@ -341,10 +341,11 @@ nsIOService::GetInstance() {
return gIOService;
}
NS_IMPL_THREADSAFE_ISUPPORTS5(nsIOService,
NS_IMPL_THREADSAFE_ISUPPORTS6(nsIOService,
nsIIOService,
nsIIOService2,
nsINetUtil,
nsISpeculativeConnect,
nsIObserver,
nsISupportsWeakReference)
@ -608,10 +609,47 @@ nsIOService::NewChannelFromURI(nsIURI *aURI, nsIChannel **result)
return NewChannelFromURIWithProxyFlags(aURI, nsnull, 0, result);
}
void
nsIOService::LookupProxyInfo(nsIURI *aURI,
nsIURI *aProxyURI,
PRUint32 aProxyFlags,
nsCString *aScheme,
nsIProxyInfo **outPI)
{
nsresult rv;
nsCOMPtr<nsIProxyInfo> pi;
if (!mProxyService) {
mProxyService = do_GetService(NS_PROTOCOLPROXYSERVICE_CONTRACTID);
if (!mProxyService)
NS_WARNING("failed to get protocol proxy service");
}
if (mProxyService) {
PRUint32 flags = 0;
if (aScheme->EqualsLiteral("http") || aScheme->EqualsLiteral("https"))
flags = nsIProtocolProxyService::RESOLVE_NON_BLOCKING;
rv = mProxyService->Resolve(aProxyURI ? aProxyURI : aURI, aProxyFlags,
getter_AddRefs(pi));
if (rv == NS_BASE_STREAM_WOULD_BLOCK) {
// Use an UNKNOWN proxy to defer resolution and avoid blocking.
rv = mProxyService->NewProxyInfo(NS_LITERAL_CSTRING("unknown"),
NS_LITERAL_CSTRING(""),
-1, 0, 0, nsnull,
getter_AddRefs(pi));
}
if (NS_FAILED(rv))
pi = nsnull;
}
*outPI = pi;
if (pi)
pi.forget();
}
NS_IMETHODIMP
nsIOService::NewChannelFromURIWithProxyFlags(nsIURI *aURI,
nsIURI *aProxyURI,
PRUint32 proxyFlags,
PRUint32 aProxyFlags,
nsIChannel **result)
{
nsresult rv;
@ -636,27 +674,7 @@ nsIOService::NewChannelFromURIWithProxyFlags(nsIURI *aURI,
// skip this step. This allows us to lazily load the PPS at startup.
if (protoFlags & nsIProtocolHandler::ALLOWS_PROXY) {
nsCOMPtr<nsIProxyInfo> pi;
if (!mProxyService) {
mProxyService = do_GetService(NS_PROTOCOLPROXYSERVICE_CONTRACTID);
if (!mProxyService)
NS_WARNING("failed to get protocol proxy service");
}
if (mProxyService) {
PRUint32 flags = 0;
if (scheme.EqualsLiteral("http") || scheme.EqualsLiteral("https"))
flags = nsIProtocolProxyService::RESOLVE_NON_BLOCKING;
rv = mProxyService->Resolve(aProxyURI ? aProxyURI : aURI, proxyFlags,
getter_AddRefs(pi));
if (rv == NS_BASE_STREAM_WOULD_BLOCK) {
// Use an UNKNOWN proxy to defer resolution and avoid blocking.
rv = mProxyService->NewProxyInfo(NS_LITERAL_CSTRING("unknown"),
NS_LITERAL_CSTRING(""),
-1, 0, 0, nsnull,
getter_AddRefs(pi));
}
if (NS_FAILED(rv))
pi = nsnull;
}
LookupProxyInfo(aURI, aProxyURI, aProxyFlags, &scheme, getter_AddRefs(pi));
if (pi) {
nsCAutoString type;
if (NS_SUCCEEDED(pi->GetType(type)) && type.EqualsLiteral("http")) {
@ -1236,3 +1254,37 @@ nsIOService::ExtractCharsetFromContentType(const nsACString &aTypeHeader,
}
return NS_OK;
}
// nsISpeculativeConnect
NS_IMETHODIMP
nsIOService::SpeculativeConnect(nsIURI *aURI,
nsIInterfaceRequestor *aCallbacks,
nsIEventTarget *aTarget)
{
nsCAutoString scheme;
nsresult rv = aURI->GetScheme(scheme);
if (NS_FAILED(rv))
return rv;
// Check for proxy information. If there is a proxy configured then a
// speculative connect should not be performed because the potential
// reward is slim with tcp peers closely located to the browser.
nsCOMPtr<nsIProxyInfo> pi;
LookupProxyInfo(aURI, nsnull, 0, &scheme, getter_AddRefs(pi));
if (pi)
return NS_OK;
nsCOMPtr<nsIProtocolHandler> handler;
rv = GetProtocolHandler(scheme.get(), getter_AddRefs(handler));
if (NS_FAILED(rv))
return rv;
nsCOMPtr<nsISpeculativeConnect> speculativeHandler =
do_QueryInterface(handler);
if (!handler)
return NS_OK;
return speculativeHandler->SpeculativeConnect(aURI,
aCallbacks,
aTarget);
}

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

@ -58,6 +58,7 @@
#include "nsCategoryCache.h"
#include "nsINetworkLinkService.h"
#include "nsAsyncRedirectVerifyHelper.h"
#include "nsISpeculativeConnect.h"
#define NS_N(x) (sizeof(x)/sizeof(*x))
@ -74,6 +75,7 @@ class nsIPrefBranch;
class nsIOService : public nsIIOService2
, public nsIObserver
, public nsINetUtil
, public nsISpeculativeConnect
, public nsSupportsWeakReference
{
public:
@ -82,6 +84,7 @@ public:
NS_DECL_NSIIOSERVICE2
NS_DECL_NSIOBSERVER
NS_DECL_NSINETUTIL
NS_DECL_NSISPECULATIVECONNECT
// Gets the singleton instance of the IO Service, creating it as needed
// Returns nsnull on out of memory or failure to initialize.
@ -135,6 +138,10 @@ private:
nsresult InitializeSocketTransportService();
nsresult InitializeNetworkLinkService();
// consolidated helper function
void LookupProxyInfo(nsIURI *aURI, nsIURI *aProxyURI, PRUint32 aProxyFlags,
nsCString *aScheme, nsIProxyInfo **outPI);
private:
bool mOffline;
bool mOfflineForProfileChange;

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

@ -112,6 +112,7 @@ CPPSRCS = \
HttpChannelParentListener.cpp \
SpdySession.cpp \
SpdyStream.cpp \
NullHttpTransaction.cpp \
$(NULL)
LOCAL_INCLUDES = \

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

@ -0,0 +1,223 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set sw=2 ts=8 et tw=80 : */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla.
*
* The Initial Developer of the Original Code is
* Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2012
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Patrick McManus <mcmanus@ducksong.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsHttp.h"
#include "NullHttpTransaction.h"
#include "nsProxyRelease.h"
#include "nsHttpHandler.h"
namespace mozilla {
namespace net {
NS_IMPL_THREADSAFE_ISUPPORTS0(NullHttpTransaction);
NullHttpTransaction::NullHttpTransaction(nsHttpConnectionInfo *ci,
nsIInterfaceRequestor *callbacks,
nsIEventTarget *target,
PRUint8 caps)
: mStatus(NS_OK)
, mCaps(caps)
, mCallbacks(callbacks)
, mEventTarget(target)
, mConnectionInfo(ci)
, mRequestHead(nsnull)
{
}
NullHttpTransaction::~NullHttpTransaction()
{
if (mCallbacks) {
nsIInterfaceRequestor *cbs = nsnull;
mCallbacks.swap(cbs);
NS_ProxyRelease(mEventTarget, cbs);
}
delete mRequestHead;
}
void
NullHttpTransaction::SetConnection(nsAHttpConnection *conn)
{
mConnection = conn;
}
nsAHttpConnection *
NullHttpTransaction::Connection()
{
return mConnection.get();
}
void
NullHttpTransaction::GetSecurityCallbacks(nsIInterfaceRequestor **outCB,
nsIEventTarget **outTarget)
{
nsCOMPtr<nsIInterfaceRequestor> copyCB(mCallbacks);
*outCB = copyCB;
copyCB.forget();
if (outTarget) {
nsCOMPtr<nsIEventTarget> copyET(mEventTarget);
*outTarget = copyET;
copyET.forget();
}
}
void
NullHttpTransaction::OnTransportStatus(nsITransport* transport,
nsresult status, PRUint64 progress)
{
}
bool
NullHttpTransaction::IsDone()
{
return true;
}
nsresult
NullHttpTransaction::Status()
{
return mStatus;
}
PRUint8
NullHttpTransaction::Caps()
{
return mCaps;
}
PRUint32
NullHttpTransaction::Available()
{
return 0;
}
nsresult
NullHttpTransaction::ReadSegments(nsAHttpSegmentReader *reader,
PRUint32 count, PRUint32 *countRead)
{
*countRead = 0;
return NS_BASE_STREAM_CLOSED;
}
nsresult
NullHttpTransaction::WriteSegments(nsAHttpSegmentWriter *writer,
PRUint32 count, PRUint32 *countWritten)
{
*countWritten = 0;
return NS_BASE_STREAM_CLOSED;
}
PRUint32
NullHttpTransaction::Http1xTransactionCount()
{
return 0;
}
nsHttpRequestHead *
NullHttpTransaction::RequestHead()
{
// We suport a requesthead at all so that a CONNECT tunnel transaction
// can obtain a Host header from it, but we lazy-popualate that header.
if (!mRequestHead) {
mRequestHead = new nsHttpRequestHead();
nsCAutoString hostHeader;
nsCString host(mConnectionInfo->GetHost());
nsresult rv = nsHttpHandler::GenerateHostPort(host,
mConnectionInfo->Port(),
hostHeader);
if (NS_SUCCEEDED(rv))
mRequestHead->SetHeader(nsHttp::Host, hostHeader);
// CONNECT tunnels may also want Proxy-Authorization but that is a lot
// harder to determine, so for now we will let those connections fail in
// the NullHttpTransaction and let them be retried from the pending queue
// with a bound transcation
}
return mRequestHead;
}
nsresult
NullHttpTransaction::TakeSubTransactions(
nsTArray<nsRefPtr<nsAHttpTransaction> > &outTransactions)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
void
NullHttpTransaction::SetSSLConnectFailed()
{
}
void
NullHttpTransaction::Close(nsresult reason)
{
mStatus = reason;
mConnection = nsnull;
}
nsresult
NullHttpTransaction::AddTransaction(nsAHttpTransaction *trans)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
PRUint32
NullHttpTransaction::PipelineDepth()
{
return 0;
}
nsresult
NullHttpTransaction::SetPipelinePosition(PRInt32 position)
{
return NS_OK;
}
PRInt32
NullHttpTransaction::PipelinePosition()
{
return 1;
}
} // namespace mozilla::net
} // namespace mozilla

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше