mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1138288 - Refactor nsWindow/nsScreen for multiple screen/window case. r=mwu
This commit is contained in:
parent
d6ebb05312
commit
4fac76791d
@ -31,7 +31,8 @@ class nsScreenGonk : public nsBaseScreen
|
||||
typedef mozilla::hal::ScreenConfiguration ScreenConfiguration;
|
||||
|
||||
public:
|
||||
nsScreenGonk();
|
||||
nsScreenGonk(uint32_t aId, ANativeWindow* aNativeWindow);
|
||||
|
||||
~nsScreenGonk();
|
||||
|
||||
NS_IMETHOD GetId(uint32_t* aId);
|
||||
@ -42,9 +43,14 @@ public:
|
||||
NS_IMETHOD GetRotation(uint32_t* aRotation);
|
||||
NS_IMETHOD SetRotation(uint32_t aRotation);
|
||||
|
||||
uint32_t GetId();
|
||||
nsIntRect GetRect();
|
||||
float GetDpi();
|
||||
ANativeWindow* GetNativeWindow();
|
||||
nsIntRect GetNaturalBounds();
|
||||
uint32_t EffectiveScreenRotation();
|
||||
ScreenConfiguration GetConfiguration();
|
||||
bool IsPrimaryScreen();
|
||||
|
||||
void RegisterWindow(nsWindow* aWindow);
|
||||
void UnregisterWindow(nsWindow* aWindow);
|
||||
@ -56,8 +62,12 @@ public:
|
||||
}
|
||||
|
||||
protected:
|
||||
nsIntRect mScreenBounds;
|
||||
nsIntRect mVirtualBounds;
|
||||
uint32_t mId;
|
||||
int32_t mColorDepth;
|
||||
android::sp<ANativeWindow> mNativeWindow;
|
||||
float mDpi;
|
||||
nsIntRect mNaturalBounds; // Screen bounds w/o rotation taken into account.
|
||||
nsIntRect mVirtualBounds; // Screen bounds w/ rotation taken into account.
|
||||
uint32_t mScreenRotation;
|
||||
uint32_t mPhysicalScreenRotation;
|
||||
nsTArray<nsWindow*> mTopWindows;
|
||||
@ -65,6 +75,15 @@ protected:
|
||||
|
||||
class nsScreenManagerGonk final : public nsIScreenManager
|
||||
{
|
||||
public:
|
||||
enum {
|
||||
// TODO: Bug 1138287 will define more screen/display types.
|
||||
PRIMARY_SCREEN_TYPE = 0,
|
||||
|
||||
// TODO: Maintain a mapping from type to id dynamically.
|
||||
PRIMARY_SCREEN_ID = 0,
|
||||
};
|
||||
|
||||
public:
|
||||
nsScreenManagerGonk();
|
||||
|
||||
@ -77,12 +96,16 @@ public:
|
||||
void Initialize();
|
||||
void DisplayEnabled(bool aEnabled);
|
||||
|
||||
void AddScreen(uint32_t aDisplayType);
|
||||
void RemoveScreen(uint32_t aDisplayType);
|
||||
|
||||
protected:
|
||||
~nsScreenManagerGonk();
|
||||
void VsyncControl(bool aEnabled);
|
||||
uint32_t GetIdFromType(uint32_t aDisplayType);
|
||||
|
||||
bool mInitialized;
|
||||
nsCOMPtr<nsIScreen> mOneScreen;
|
||||
nsTArray<nsRefPtr<nsScreenGonk>> mScreens;
|
||||
nsRefPtr<nsRunnable> mScreenOnEvent;
|
||||
nsRefPtr<nsRunnable> mScreenOffEvent;
|
||||
};
|
||||
|
@ -134,7 +134,6 @@ nsWindow::nsWindow()
|
||||
|
||||
nsRefPtr<nsScreenManagerGonk> screenManager = nsScreenManagerGonk::GetInstance();
|
||||
screenManager->Initialize();
|
||||
mScreen = nsScreenManagerGonk::GetPrimaryScreen();
|
||||
|
||||
// This is a hack to force initialization of the compositor
|
||||
// resources, if we're going to use omtc.
|
||||
@ -150,7 +149,9 @@ nsWindow::nsWindow()
|
||||
|
||||
nsWindow::~nsWindow()
|
||||
{
|
||||
HwcComposer2D::GetInstance()->SetCompositorParent(nullptr);
|
||||
if (mScreen->IsPrimaryScreen()) {
|
||||
HwcComposer2D::GetInstance()->SetCompositorParent(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@ -397,11 +398,17 @@ nsWindow::Create(nsIWidget *aParent,
|
||||
const nsIntRect &aRect,
|
||||
nsWidgetInitData *aInitData)
|
||||
{
|
||||
nsIntRect virtualBounds;
|
||||
mScreen->GetRect(&virtualBounds.x, &virtualBounds.y,
|
||||
&virtualBounds.width, &virtualBounds.height);
|
||||
BaseCreate(aParent, IS_TOPLEVEL() ? virtualBounds : aRect,
|
||||
aInitData);
|
||||
BaseCreate(aParent, aRect, aInitData);
|
||||
|
||||
nsCOMPtr<nsIScreen> screen;
|
||||
|
||||
uint32_t screenId = aParent ? ((nsWindow*)aParent)->mScreen->GetId() :
|
||||
aInitData->mScreenId;
|
||||
|
||||
nsRefPtr<nsScreenManagerGonk> screenManager = nsScreenManagerGonk::GetInstance();
|
||||
screenManager->ScreenForId(screenId, getter_AddRefs(screen));
|
||||
|
||||
mScreen = static_cast<nsScreenGonk*>(screen.get());
|
||||
|
||||
mBounds = aRect;
|
||||
|
||||
@ -409,7 +416,7 @@ nsWindow::Create(nsIWidget *aParent,
|
||||
mVisible = false;
|
||||
|
||||
if (!aParent) {
|
||||
mBounds = virtualBounds;
|
||||
mBounds = mScreen->GetRect();
|
||||
}
|
||||
|
||||
if (!IS_TOPLEVEL()) {
|
||||
@ -418,7 +425,8 @@ nsWindow::Create(nsIWidget *aParent,
|
||||
|
||||
mScreen->RegisterWindow(this);
|
||||
|
||||
Resize(0, 0, virtualBounds.width, virtualBounds.height, false);
|
||||
Resize(0, 0, mBounds.width, mBounds.height, false);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -511,10 +519,7 @@ nsWindow::Resize(double aX,
|
||||
}
|
||||
|
||||
if (aRepaint) {
|
||||
nsIntRect virtualBounds;
|
||||
mScreen->GetRect(&virtualBounds.x, &virtualBounds.y,
|
||||
&virtualBounds.width, &virtualBounds.height);
|
||||
Invalidate(virtualBounds);
|
||||
Invalidate(mBounds);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
@ -538,7 +543,12 @@ nsWindow::SetFocus(bool aRaise)
|
||||
if (aRaise) {
|
||||
BringToTop();
|
||||
}
|
||||
gFocusedWindow = this;
|
||||
|
||||
if (!IS_TOPLEVEL() && mScreen->IsPrimaryScreen()) {
|
||||
// We should only set focused window on non-toplevel primary window.
|
||||
gFocusedWindow = this;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -587,7 +597,7 @@ nsWindow::GetNativeData(uint32_t aDataType)
|
||||
switch (aDataType) {
|
||||
case NS_NATIVE_WINDOW:
|
||||
// Called before primary display's EGLSurface creation.
|
||||
return GetGonkDisplay()->GetNativeWindow();
|
||||
return mScreen->GetNativeWindow();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
@ -748,7 +758,7 @@ nsWindow::EndRemoteDrawing()
|
||||
float
|
||||
nsWindow::GetDPI()
|
||||
{
|
||||
return GetGonkDisplay()->xdpi;
|
||||
return mScreen->GetDpi();
|
||||
}
|
||||
|
||||
double
|
||||
@ -803,7 +813,7 @@ nsWindow::GetLayerManager(PLayerTransactionChild* aShadowManager,
|
||||
}
|
||||
|
||||
CreateCompositor();
|
||||
if (mCompositorParent) {
|
||||
if (mCompositorParent && mScreen->IsPrimaryScreen()) {
|
||||
HwcComposer2D::GetInstance()->SetCompositorParent(mCompositorParent);
|
||||
}
|
||||
MOZ_ASSERT(mLayerManager);
|
||||
@ -826,10 +836,7 @@ nsWindow::BringToTop()
|
||||
mWidgetListener->WindowActivated();
|
||||
}
|
||||
|
||||
nsIntRect virtualBounds;
|
||||
mScreen->GetRect(&virtualBounds.x, &virtualBounds.y,
|
||||
&virtualBounds.width, &virtualBounds.height);
|
||||
Invalidate(virtualBounds);
|
||||
Invalidate(mBounds);
|
||||
}
|
||||
|
||||
void
|
||||
@ -874,42 +881,75 @@ nsWindow::NeedsPaint()
|
||||
Composer2D*
|
||||
nsWindow::GetComposer2D()
|
||||
{
|
||||
if (!mScreen->IsPrimaryScreen()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return HwcComposer2D::GetInstance();
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
SurfaceFormatToColorDepth(int32_t aSurfaceFormat)
|
||||
{
|
||||
switch (aSurfaceFormat) {
|
||||
case GGL_PIXEL_FORMAT_RGB_565:
|
||||
return 16;
|
||||
case GGL_PIXEL_FORMAT_RGBA_8888:
|
||||
return 32;
|
||||
}
|
||||
return 24; // GGL_PIXEL_FORMAT_RGBX_8888
|
||||
}
|
||||
|
||||
// nsScreenGonk.cpp
|
||||
|
||||
nsScreenGonk::nsScreenGonk()
|
||||
: mScreenRotation(nsIScreen::ROTATION_0_DEG)
|
||||
nsScreenGonk::nsScreenGonk(uint32_t aId, ANativeWindow* aNativeWindow)
|
||||
: mId(aId)
|
||||
, mNativeWindow(aNativeWindow)
|
||||
, mScreenRotation(nsIScreen::ROTATION_0_DEG)
|
||||
, mPhysicalScreenRotation(nsIScreen::ROTATION_0_DEG)
|
||||
{
|
||||
nsIntSize screenSize;
|
||||
|
||||
ANativeWindow *win = GetGonkDisplay()->GetNativeWindow();
|
||||
if (win->query(win, NATIVE_WINDOW_WIDTH, &screenSize.width) ||
|
||||
win->query(win, NATIVE_WINDOW_HEIGHT, &screenSize.height)) {
|
||||
int surfaceFormat;
|
||||
if (mNativeWindow->query(mNativeWindow.get(), NATIVE_WINDOW_WIDTH, &mVirtualBounds.width) ||
|
||||
mNativeWindow->query(mNativeWindow.get(), NATIVE_WINDOW_HEIGHT, &mVirtualBounds.height) ||
|
||||
mNativeWindow->query(mNativeWindow.get(), NATIVE_WINDOW_FORMAT, &surfaceFormat)) {
|
||||
NS_RUNTIMEABORT("Failed to get native window size, aborting...");
|
||||
}
|
||||
mScreenBounds = gfx::IntRect(gfx::IntPoint(0, 0), screenSize);
|
||||
|
||||
char propValue[PROPERTY_VALUE_MAX];
|
||||
property_get("ro.sf.hwrotation", propValue, "0");
|
||||
mPhysicalScreenRotation = atoi(propValue) / 90;
|
||||
mNaturalBounds = mVirtualBounds;
|
||||
|
||||
mVirtualBounds = mScreenBounds;
|
||||
if (IsPrimaryScreen()) {
|
||||
char propValue[PROPERTY_VALUE_MAX];
|
||||
property_get("ro.sf.hwrotation", propValue, "0");
|
||||
mPhysicalScreenRotation = atoi(propValue) / 90;
|
||||
}
|
||||
|
||||
mDpi = GetGonkDisplay()->xdpi;
|
||||
mColorDepth = SurfaceFormatToColorDepth(surfaceFormat);
|
||||
}
|
||||
|
||||
nsScreenGonk::~nsScreenGonk()
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
nsScreenGonk::IsPrimaryScreen()
|
||||
{
|
||||
return nsScreenManagerGonk::PRIMARY_SCREEN_ID == mId;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScreenGonk::GetId(uint32_t *outId)
|
||||
{
|
||||
*outId = 1;
|
||||
*outId = mId;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
nsScreenGonk::GetId()
|
||||
{
|
||||
return mId;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScreenGonk::GetRect(int32_t *outLeft, int32_t *outTop,
|
||||
int32_t *outWidth, int32_t *outHeight)
|
||||
@ -923,6 +963,12 @@ nsScreenGonk::GetRect(int32_t *outLeft, int32_t *outTop,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsIntRect
|
||||
nsScreenGonk::GetRect()
|
||||
{
|
||||
return mVirtualBounds;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScreenGonk::GetAvailRect(int32_t *outLeft, int32_t *outTop,
|
||||
int32_t *outWidth, int32_t *outHeight)
|
||||
@ -930,31 +976,20 @@ nsScreenGonk::GetAvailRect(int32_t *outLeft, int32_t *outTop,
|
||||
return GetRect(outLeft, outTop, outWidth, outHeight);
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
ColorDepth()
|
||||
{
|
||||
switch (GetGonkDisplay()->surfaceformat) {
|
||||
case GGL_PIXEL_FORMAT_RGB_565:
|
||||
return 16;
|
||||
case GGL_PIXEL_FORMAT_RGBA_8888:
|
||||
return 32;
|
||||
}
|
||||
return 24; // GGL_PIXEL_FORMAT_RGBX_8888
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScreenGonk::GetPixelDepth(int32_t *aPixelDepth)
|
||||
{
|
||||
// XXX: this should actually return 32 when we're using 24-bit
|
||||
// color, because we use RGBX.
|
||||
*aPixelDepth = ColorDepth();
|
||||
*aPixelDepth = mColorDepth;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScreenGonk::GetColorDepth(int32_t *aColorDepth)
|
||||
{
|
||||
return GetPixelDepth(aColorDepth);
|
||||
*aColorDepth = mColorDepth;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -964,6 +999,18 @@ nsScreenGonk::GetRotation(uint32_t* aRotation)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
float
|
||||
nsScreenGonk::GetDpi()
|
||||
{
|
||||
return mDpi;
|
||||
}
|
||||
|
||||
ANativeWindow*
|
||||
nsScreenGonk::GetNativeWindow()
|
||||
{
|
||||
return mNativeWindow.get();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScreenGonk::SetRotation(uint32_t aRotation)
|
||||
{
|
||||
@ -980,10 +1027,10 @@ nsScreenGonk::SetRotation(uint32_t aRotation)
|
||||
if (rotation == nsIScreen::ROTATION_90_DEG ||
|
||||
rotation == nsIScreen::ROTATION_270_DEG) {
|
||||
mVirtualBounds = nsIntRect(0, 0,
|
||||
mScreenBounds.height,
|
||||
mScreenBounds.width);
|
||||
mNaturalBounds.height,
|
||||
mNaturalBounds.width);
|
||||
} else {
|
||||
mVirtualBounds = mScreenBounds;
|
||||
mVirtualBounds = mNaturalBounds;
|
||||
}
|
||||
|
||||
nsAppShell::NotifyScreenRotation();
|
||||
@ -1000,7 +1047,7 @@ nsScreenGonk::SetRotation(uint32_t aRotation)
|
||||
nsIntRect
|
||||
nsScreenGonk::GetNaturalBounds()
|
||||
{
|
||||
return mScreenBounds;
|
||||
return mNaturalBounds;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
@ -1039,12 +1086,12 @@ ScreenConfiguration
|
||||
nsScreenGonk::GetConfiguration()
|
||||
{
|
||||
ScreenOrientation orientation = ComputeOrientation(mScreenRotation,
|
||||
mScreenBounds.Size());
|
||||
uint32_t colorDepth = ColorDepth();
|
||||
mNaturalBounds.Size());
|
||||
|
||||
// NB: perpetuating colorDepth == pixelDepth illusion here, for
|
||||
// consistency.
|
||||
return ScreenConfiguration(mVirtualBounds, orientation,
|
||||
colorDepth, colorDepth);
|
||||
mColorDepth, mColorDepth);
|
||||
}
|
||||
|
||||
void
|
||||
@ -1071,7 +1118,6 @@ NS_IMPL_ISUPPORTS(nsScreenManagerGonk, nsIScreenManager)
|
||||
nsScreenManagerGonk::nsScreenManagerGonk()
|
||||
: mInitialized(false)
|
||||
{
|
||||
mOneScreen = new nsScreenGonk();
|
||||
}
|
||||
|
||||
nsScreenManagerGonk::~nsScreenManagerGonk()
|
||||
@ -1110,6 +1156,8 @@ nsScreenManagerGonk::Initialize()
|
||||
mScreenOffEvent = new ScreenOnOffEvent(false);
|
||||
GetGonkDisplay()->OnEnabled(displayEnabledCallback);
|
||||
|
||||
AddScreen(PRIMARY_SCREEN_TYPE);
|
||||
|
||||
nsAppShell::NotifyScreenInitialized();
|
||||
mInitialized = true;
|
||||
}
|
||||
@ -1127,7 +1175,7 @@ nsScreenManagerGonk::DisplayEnabled(bool aEnabled)
|
||||
NS_IMETHODIMP
|
||||
nsScreenManagerGonk::GetPrimaryScreen(nsIScreen **outScreen)
|
||||
{
|
||||
NS_IF_ADDREF(*outScreen = mOneScreen.get());
|
||||
NS_IF_ADDREF(*outScreen = mScreens[0].get());
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -1135,7 +1183,15 @@ NS_IMETHODIMP
|
||||
nsScreenManagerGonk::ScreenForId(uint32_t aId,
|
||||
nsIScreen **outScreen)
|
||||
{
|
||||
return GetPrimaryScreen(outScreen);
|
||||
for (size_t i = 0; i < mScreens.Length(); i++) {
|
||||
if (mScreens[i]->GetId() == aId) {
|
||||
NS_IF_ADDREF(*outScreen = mScreens[i].get());
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
*outScreen = nullptr;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -1145,19 +1201,29 @@ nsScreenManagerGonk::ScreenForRect(int32_t inLeft,
|
||||
int32_t inHeight,
|
||||
nsIScreen **outScreen)
|
||||
{
|
||||
// Since all screens have independent coordinate system, we could
|
||||
// only return the primary screen no matter what rect is given.
|
||||
return GetPrimaryScreen(outScreen);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScreenManagerGonk::ScreenForNativeWidget(void *aWidget, nsIScreen **outScreen)
|
||||
{
|
||||
return GetPrimaryScreen(outScreen);
|
||||
for (size_t i = 0; i < mScreens.Length(); i++) {
|
||||
if (aWidget == mScreens[i]->GetNativeWindow()) {
|
||||
NS_IF_ADDREF(*outScreen = mScreens[i].get());
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
*outScreen = nullptr;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScreenManagerGonk::GetNumberOfScreens(uint32_t *aNumberOfScreens)
|
||||
{
|
||||
*aNumberOfScreens = 1;
|
||||
*aNumberOfScreens = mScreens.Length();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -1189,3 +1255,39 @@ nsScreenManagerGonk::VsyncControl(bool aEnabled)
|
||||
display.DisableVsync();
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t
|
||||
nsScreenManagerGonk::GetIdFromType(uint32_t aDisplayType)
|
||||
{
|
||||
// This is the only place where we make the assumption that
|
||||
// display type is equivalent to screen id.
|
||||
|
||||
// Bug 1138287 will address the conversion from type to id.
|
||||
return aDisplayType;
|
||||
}
|
||||
|
||||
void
|
||||
nsScreenManagerGonk::AddScreen(uint32_t aDisplayType)
|
||||
{
|
||||
// We currently only support adding primary screen.
|
||||
MOZ_ASSERT(PRIMARY_SCREEN_TYPE == aDisplayType);
|
||||
|
||||
uint32_t id = GetIdFromType(aDisplayType);
|
||||
|
||||
ANativeWindow* win = GetGonkDisplay()->GetNativeWindow();
|
||||
nsScreenGonk* screen = new nsScreenGonk(id, win);
|
||||
|
||||
mScreens.AppendElement(screen);
|
||||
}
|
||||
|
||||
void
|
||||
nsScreenManagerGonk::RemoveScreen(uint32_t aDisplayType)
|
||||
{
|
||||
uint32_t screenId = GetIdFromType(aDisplayType);
|
||||
for (size_t i = 0; i < mScreens.Length(); i++) {
|
||||
if (mScreens[i]->GetId() == screenId) {
|
||||
mScreens.RemoveElementAt(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user