summaryrefslogtreecommitdiffstats
path: root/widget/gonk/nsScreenManagerGonk.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'widget/gonk/nsScreenManagerGonk.cpp')
-rw-r--r--widget/gonk/nsScreenManagerGonk.cpp1081
1 files changed, 0 insertions, 1081 deletions
diff --git a/widget/gonk/nsScreenManagerGonk.cpp b/widget/gonk/nsScreenManagerGonk.cpp
deleted file mode 100644
index e359fd195..000000000
--- a/widget/gonk/nsScreenManagerGonk.cpp
+++ /dev/null
@@ -1,1081 +0,0 @@
-/* Copyright 2012 Mozilla Foundation and Mozilla contributors
- *
- * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "android/log.h"
-#include "GLContext.h"
-#include "gfxPrefs.h"
-#include "gfxUtils.h"
-#include "mozilla/MouseEvents.h"
-#include "mozilla/TouchEvents.h"
-#include "mozilla/Hal.h"
-#include "libdisplay/BootAnimation.h"
-#include "libdisplay/GonkDisplay.h"
-#include "nsScreenManagerGonk.h"
-#include "nsThreadUtils.h"
-#include "HwcComposer2D.h"
-#include "VsyncSource.h"
-#include "nsWindow.h"
-#include "mozilla/ClearOnShutdown.h"
-#include "mozilla/layers/CompositorBridgeParent.h"
-#include "mozilla/layers/CompositorThread.h"
-#include "mozilla/Services.h"
-#include "mozilla/ProcessPriorityManager.h"
-#include "nsIdleService.h"
-#include "nsIObserverService.h"
-#include "nsAppShell.h"
-#include "nsProxyRelease.h"
-#include "nsTArray.h"
-#include "pixelflinger/format.h"
-#include "nsIDisplayInfo.h"
-#include "base/task.h"
-
-#if ANDROID_VERSION >= 17
-#include "libdisplay/DisplaySurface.h"
-#endif
-
-#define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "nsScreenGonk" , ## args)
-#define LOGW(args...) __android_log_print(ANDROID_LOG_WARN, "nsScreenGonk", ## args)
-#define LOGE(args...) __android_log_print(ANDROID_LOG_ERROR, "nsScreenGonk", ## args)
-
-using namespace mozilla;
-using namespace mozilla::hal;
-using namespace mozilla::gfx;
-using namespace mozilla::gl;
-using namespace mozilla::layers;
-using namespace mozilla::dom;
-
-namespace {
-
-class ScreenOnOffEvent : public mozilla::Runnable {
-public:
- ScreenOnOffEvent(bool on)
- : mIsOn(on)
- {}
-
- NS_IMETHOD Run() override {
- // Notify observers that the screen state has just changed.
- nsCOMPtr<nsIObserverService> observerService = mozilla::services::GetObserverService();
- if (observerService) {
- observerService->NotifyObservers(
- nullptr, "screen-state-changed",
- mIsOn ? u"on" : u"off"
- );
- }
-
- RefPtr<nsScreenGonk> screen = nsScreenManagerGonk::GetPrimaryScreen();
- const nsTArray<nsWindow*>& windows = screen->GetTopWindows();
-
- for (uint32_t i = 0; i < windows.Length(); i++) {
- nsWindow *win = windows[i];
-
- if (nsIWidgetListener* listener = win->GetWidgetListener()) {
- listener->SizeModeChanged(mIsOn ? nsSizeMode_Fullscreen : nsSizeMode_Minimized);
- }
- }
-
- return NS_OK;
- }
-
-private:
- bool mIsOn;
-};
-
-static void
-displayEnabledCallback(bool enabled)
-{
- RefPtr<nsScreenManagerGonk> screenManager = nsScreenManagerGonk::GetInstance();
- screenManager->DisplayEnabled(enabled);
-}
-
-} // namespace
-
-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(uint32_t aId,
- GonkDisplay::DisplayType aDisplayType,
- const GonkDisplay::NativeData& aNativeData,
- NotifyDisplayChangedEvent aEventVisibility)
- : mId(aId)
- , mEventVisibility(aEventVisibility)
- , mNativeWindow(aNativeData.mNativeWindow)
- , mDpi(aNativeData.mXdpi)
- , mScreenRotation(nsIScreen::ROTATION_0_DEG)
- , mPhysicalScreenRotation(nsIScreen::ROTATION_0_DEG)
-#if ANDROID_VERSION >= 17
- , mDisplaySurface(aNativeData.mDisplaySurface)
-#endif
- , mIsMirroring(false)
- , mDisplayType(aDisplayType)
- , mEGLDisplay(EGL_NO_DISPLAY)
- , mEGLSurface(EGL_NO_SURFACE)
- , mGLContext(nullptr)
- , mFramebuffer(nullptr)
- , mMappedBuffer(nullptr)
-{
- 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, &mSurfaceFormat)) {
- NS_RUNTIMEABORT("Failed to get native window size, aborting...");
- }
-
- mNaturalBounds = mVirtualBounds;
-
- if (IsPrimaryScreen()) {
- char propValue[PROPERTY_VALUE_MAX];
- property_get("ro.sf.hwrotation", propValue, "0");
- mPhysicalScreenRotation = atoi(propValue) / 90;
- }
-
- mColorDepth = SurfaceFormatToColorDepth(mSurfaceFormat);
-}
-
-static void
-ReleaseGLContextSync(mozilla::gl::GLContext* aGLContext)
-{
- MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
- aGLContext->Release();
-}
-
-nsScreenGonk::~nsScreenGonk()
-{
- // Release GLContext on compositor thread
- if (mGLContext) {
- CompositorThreadHolder::Loop()->PostTask(
- NewRunnableFunction(&ReleaseGLContextSync,
- mGLContext.forget().take()));
- mGLContext = nullptr;
- }
-}
-
-bool
-nsScreenGonk::IsPrimaryScreen()
-{
- return mDisplayType == GonkDisplay::DISPLAY_PRIMARY;
-}
-
-NS_IMETHODIMP
-nsScreenGonk::GetId(uint32_t *outId)
-{
- *outId = mId;
- return NS_OK;
-}
-
-uint32_t
-nsScreenGonk::GetId()
-{
- return mId;
-}
-
-NotifyDisplayChangedEvent
-nsScreenGonk::GetEventVisibility()
-{
- return mEventVisibility;
-}
-
-NS_IMETHODIMP
-nsScreenGonk::GetRect(int32_t *outLeft, int32_t *outTop,
- int32_t *outWidth, int32_t *outHeight)
-{
- *outLeft = mVirtualBounds.x;
- *outTop = mVirtualBounds.y;
-
- *outWidth = mVirtualBounds.width;
- *outHeight = mVirtualBounds.height;
-
- return NS_OK;
-}
-
-LayoutDeviceIntRect
-nsScreenGonk::GetRect()
-{
- return mVirtualBounds;
-}
-
-NS_IMETHODIMP
-nsScreenGonk::GetAvailRect(int32_t *outLeft, int32_t *outTop,
- int32_t *outWidth, int32_t *outHeight)
-{
- return GetRect(outLeft, outTop, outWidth, outHeight);
-}
-
-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 = mColorDepth;
- return NS_OK;
-}
-
-NS_IMETHODIMP
-nsScreenGonk::GetColorDepth(int32_t *aColorDepth)
-{
- *aColorDepth = mColorDepth;
- return NS_OK;
-}
-
-NS_IMETHODIMP
-nsScreenGonk::GetRotation(uint32_t* aRotation)
-{
- *aRotation = mScreenRotation;
- return NS_OK;
-}
-
-float
-nsScreenGonk::GetDpi()
-{
- return mDpi;
-}
-
-int32_t
-nsScreenGonk::GetSurfaceFormat()
-{
- return mSurfaceFormat;
-}
-
-ANativeWindow*
-nsScreenGonk::GetNativeWindow()
-{
- return mNativeWindow.get();
-}
-
-NS_IMETHODIMP
-nsScreenGonk::SetRotation(uint32_t aRotation)
-{
- if (!(aRotation <= ROTATION_270_DEG)) {
- return NS_ERROR_ILLEGAL_VALUE;
- }
-
- if (mScreenRotation == aRotation) {
- return NS_OK;
- }
-
- mScreenRotation = aRotation;
- uint32_t rotation = EffectiveScreenRotation();
- if (rotation == nsIScreen::ROTATION_90_DEG ||
- rotation == nsIScreen::ROTATION_270_DEG) {
- mVirtualBounds = LayoutDeviceIntRect(0, 0,
- mNaturalBounds.height,
- mNaturalBounds.width);
- } else {
- mVirtualBounds = mNaturalBounds;
- }
-
- nsAppShell::NotifyScreenRotation();
-
- for (unsigned int i = 0; i < mTopWindows.Length(); i++) {
- mTopWindows[i]->Resize(mVirtualBounds.width,
- mVirtualBounds.height,
- true);
- }
-
- return NS_OK;
-}
-
-LayoutDeviceIntRect
-nsScreenGonk::GetNaturalBounds()
-{
- return mNaturalBounds;
-}
-
-uint32_t
-nsScreenGonk::EffectiveScreenRotation()
-{
- return (mScreenRotation + mPhysicalScreenRotation) % (360 / 90);
-}
-
-// NB: This isn't gonk-specific, but gonk is the only widget backend
-// that does this calculation itself, currently.
-static ScreenOrientationInternal
-ComputeOrientation(uint32_t aRotation, const LayoutDeviceIntSize& aScreenSize)
-{
- bool naturallyPortrait = (aScreenSize.height > aScreenSize.width);
- switch (aRotation) {
- case nsIScreen::ROTATION_0_DEG:
- return (naturallyPortrait ? eScreenOrientation_PortraitPrimary :
- eScreenOrientation_LandscapePrimary);
- case nsIScreen::ROTATION_90_DEG:
- // Arbitrarily choosing 90deg to be primary "unnatural"
- // rotation.
- return (naturallyPortrait ? eScreenOrientation_LandscapePrimary :
- eScreenOrientation_PortraitPrimary);
- case nsIScreen::ROTATION_180_DEG:
- return (naturallyPortrait ? eScreenOrientation_PortraitSecondary :
- eScreenOrientation_LandscapeSecondary);
- case nsIScreen::ROTATION_270_DEG:
- return (naturallyPortrait ? eScreenOrientation_LandscapeSecondary :
- eScreenOrientation_PortraitSecondary);
- default:
- MOZ_CRASH("Gonk screen must always have a known rotation");
- }
-}
-
-static uint16_t
-RotationToAngle(uint32_t aRotation)
-{
- uint16_t angle = 90 * aRotation;
- MOZ_ASSERT(angle == 0 || angle == 90 || angle == 180 || angle == 270);
- return angle;
-}
-
-ScreenConfiguration
-nsScreenGonk::GetConfiguration()
-{
- ScreenOrientationInternal orientation =
- ComputeOrientation(mScreenRotation, mNaturalBounds.Size());
-
- // NB: perpetuating colorDepth == pixelDepth illusion here, for
- // consistency.
- return ScreenConfiguration(mVirtualBounds.ToUnknownRect(), orientation,
- RotationToAngle(mScreenRotation),
- mColorDepth, mColorDepth);
-}
-
-void
-nsScreenGonk::RegisterWindow(nsWindow* aWindow)
-{
- mTopWindows.AppendElement(aWindow);
-}
-
-void
-nsScreenGonk::UnregisterWindow(nsWindow* aWindow)
-{
- mTopWindows.RemoveElement(aWindow);
-}
-
-void
-nsScreenGonk::BringToTop(nsWindow* aWindow)
-{
- mTopWindows.RemoveElement(aWindow);
- mTopWindows.InsertElementAt(0, aWindow);
-}
-
-static gralloc_module_t const*
-gralloc_module()
-{
- hw_module_t const *module;
- if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module)) {
- return nullptr;
- }
- return reinterpret_cast<gralloc_module_t const*>(module);
-}
-
-static SurfaceFormat
-HalFormatToSurfaceFormat(int aHalFormat)
-{
- switch (aHalFormat) {
- case HAL_PIXEL_FORMAT_RGBA_8888:
- // Needs RB swap
- return SurfaceFormat::B8G8R8A8;
- case HAL_PIXEL_FORMAT_RGBX_8888:
- // Needs RB swap
- return SurfaceFormat::B8G8R8X8;
- case HAL_PIXEL_FORMAT_BGRA_8888:
- return SurfaceFormat::B8G8R8A8;
- case HAL_PIXEL_FORMAT_RGB_565:
- return SurfaceFormat::R5G6B5_UINT16;
- default:
- MOZ_CRASH("Unhandled HAL pixel format");
- return SurfaceFormat::UNKNOWN; // not reached
- }
-}
-
-static bool
-NeedsRBSwap(int aHalFormat)
-{
- switch (aHalFormat) {
- case HAL_PIXEL_FORMAT_RGBA_8888:
- return true;
- case HAL_PIXEL_FORMAT_RGBX_8888:
- return true;
- case HAL_PIXEL_FORMAT_BGRA_8888:
- return false;
- case HAL_PIXEL_FORMAT_RGB_565:
- return false;
- default:
- MOZ_CRASH("Unhandled HAL pixel format");
- return false; // not reached
- }
-}
-
-already_AddRefed<DrawTarget>
-nsScreenGonk::StartRemoteDrawing()
-{
- MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
- MOZ_ASSERT(!mFramebuffer);
- MOZ_ASSERT(!mMappedBuffer);
-
- mFramebuffer = DequeueBuffer();
- int width = mFramebuffer->width, height = mFramebuffer->height;
- if (gralloc_module()->lock(gralloc_module(), mFramebuffer->handle,
- GRALLOC_USAGE_SW_READ_NEVER |
- GRALLOC_USAGE_SW_WRITE_OFTEN |
- GRALLOC_USAGE_HW_FB,
- 0, 0, width, height,
- reinterpret_cast<void**>(&mMappedBuffer))) {
- EndRemoteDrawing();
- return nullptr;
- }
- SurfaceFormat format = HalFormatToSurfaceFormat(GetSurfaceFormat());
- mFramebufferTarget = Factory::CreateDrawTargetForData(
- BackendType::CAIRO,
- mMappedBuffer,
- IntSize(width, height),
- mFramebuffer->stride * gfx::BytesPerPixel(format),
- format);
- if (!mFramebufferTarget) {
- MOZ_CRASH("nsWindow::StartRemoteDrawing failed in CreateDrawTargetForData");
- }
- if (!mBackBuffer ||
- mBackBuffer->GetSize() != mFramebufferTarget->GetSize() ||
- mBackBuffer->GetFormat() != mFramebufferTarget->GetFormat()) {
- mBackBuffer = mFramebufferTarget->CreateSimilarDrawTarget(
- mFramebufferTarget->GetSize(), mFramebufferTarget->GetFormat());
- }
- RefPtr<DrawTarget> buffer(mBackBuffer);
- return buffer.forget();
-}
-
-void
-nsScreenGonk::EndRemoteDrawing()
-{
- MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
-
- if (mFramebufferTarget && mFramebuffer) {
- IntSize size = mFramebufferTarget->GetSize();
- Rect rect(0, 0, size.width, size.height);
- RefPtr<SourceSurface> source = mBackBuffer->Snapshot();
- mFramebufferTarget->DrawSurface(source, rect, rect);
-
- // Convert from BGR to RGB
- // XXX this is a temporary solution. It consumes extra cpu cycles,
- // it should not be used on product device.
- if (NeedsRBSwap(GetSurfaceFormat())) {
- LOGE("Very slow composition path, it should not be used on product!!!");
- SurfaceFormat format = HalFormatToSurfaceFormat(GetSurfaceFormat());
- gfxUtils::ConvertBGRAtoRGBA(
- mMappedBuffer,
- mFramebuffer->stride * mFramebuffer->height * gfx::BytesPerPixel(format));
- }
- }
- if (mMappedBuffer) {
- MOZ_ASSERT(mFramebuffer);
- gralloc_module()->unlock(gralloc_module(), mFramebuffer->handle);
- mMappedBuffer = nullptr;
- }
- if (mFramebuffer) {
- QueueBuffer(mFramebuffer);
- }
- mFramebuffer = nullptr;
- mFramebufferTarget = nullptr;
-}
-
-ANativeWindowBuffer*
-nsScreenGonk::DequeueBuffer()
-{
- ANativeWindowBuffer* buf = nullptr;
-#if ANDROID_VERSION >= 17
- int fenceFd = -1;
- mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf, &fenceFd);
- android::sp<android::Fence> fence(new android::Fence(fenceFd));
-#if ANDROID_VERSION == 17
- fence->waitForever(1000, "nsScreenGonk_DequeueBuffer");
- // 1000 is what Android uses. It is a warning timeout in ms.
- // This timeout was removed in ANDROID_VERSION 18.
-#else
- fence->waitForever("nsScreenGonk_DequeueBuffer");
-#endif
-#else
- mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf);
-#endif
- return buf;
-}
-
-bool
-nsScreenGonk::QueueBuffer(ANativeWindowBuffer* buf)
-{
-#if ANDROID_VERSION >= 17
- int ret = mNativeWindow->queueBuffer(mNativeWindow.get(), buf, -1);
- return ret == 0;
-#else
- int ret = mNativeWindow->queueBuffer(mNativeWindow.get(), buf);
- return ret == 0;
-#endif
-}
-
-nsresult
-nsScreenGonk::MakeSnapshot(ANativeWindowBuffer* aBuffer)
-{
- MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
- MOZ_ASSERT(aBuffer);
-
- layers::CompositorBridgeParent* compositorParent = mCompositorBridgeParent;
- if (!compositorParent) {
- return NS_ERROR_FAILURE;
- }
-
- int width = aBuffer->width, height = aBuffer->height;
- uint8_t* mappedBuffer = nullptr;
- if (gralloc_module()->lock(gralloc_module(), aBuffer->handle,
- GRALLOC_USAGE_SW_READ_OFTEN |
- GRALLOC_USAGE_SW_WRITE_OFTEN,
- 0, 0, width, height,
- reinterpret_cast<void**>(&mappedBuffer))) {
- return NS_ERROR_FAILURE;
- }
-
- SurfaceFormat format = HalFormatToSurfaceFormat(GetSurfaceFormat());
- RefPtr<DrawTarget> mTarget =
- Factory::CreateDrawTargetForData(
- BackendType::CAIRO,
- mappedBuffer,
- IntSize(width, height),
- aBuffer->stride * gfx::BytesPerPixel(format),
- format);
- if (!mTarget) {
- return NS_ERROR_FAILURE;
- }
-
- gfx::IntRect rect = GetRect().ToUnknownRect();
- compositorParent->ForceComposeToTarget(mTarget, &rect);
-
- // Convert from BGR to RGB
- // XXX this is a temporary solution. It consumes extra cpu cycles,
- if (NeedsRBSwap(GetSurfaceFormat())) {
- LOGE("Slow path of making Snapshot!!!");
- SurfaceFormat format = HalFormatToSurfaceFormat(GetSurfaceFormat());
- gfxUtils::ConvertBGRAtoRGBA(
- mappedBuffer,
- aBuffer->stride * aBuffer->height * gfx::BytesPerPixel(format));
- mappedBuffer = nullptr;
- }
- gralloc_module()->unlock(gralloc_module(), aBuffer->handle);
- return NS_OK;
-}
-
-void
-nsScreenGonk::SetCompositorBridgeParent(layers::CompositorBridgeParent* aCompositorBridgeParent)
-{
- MOZ_ASSERT(NS_IsMainThread());
- mCompositorBridgeParent = aCompositorBridgeParent;
-}
-
-#if ANDROID_VERSION >= 17
-android::DisplaySurface*
-nsScreenGonk::GetDisplaySurface()
-{
- return mDisplaySurface.get();
-}
-
-int
-nsScreenGonk::GetPrevDispAcquireFd()
-{
- if (!mDisplaySurface.get()) {
- return -1;
- }
- return mDisplaySurface->GetPrevDispAcquireFd();
-}
-#endif
-
-GonkDisplay::DisplayType
-nsScreenGonk::GetDisplayType()
-{
- return mDisplayType;
-}
-
-void
-nsScreenGonk::SetEGLInfo(hwc_display_t aDisplay,
- hwc_surface_t aSurface,
- gl::GLContext* aGLContext)
-{
- MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
- mEGLDisplay = aDisplay;
- mEGLSurface = aSurface;
- mGLContext = aGLContext;
-}
-
-hwc_display_t
-nsScreenGonk::GetEGLDisplay()
-{
- MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
- return mEGLDisplay;
-}
-
-hwc_surface_t
-nsScreenGonk::GetEGLSurface()
-{
- MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
- return mEGLSurface;
-}
-
-already_AddRefed<mozilla::gl::GLContext>
-nsScreenGonk::GetGLContext()
-{
- MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
- RefPtr<mozilla::gl::GLContext>glContext = mGLContext;
- return glContext.forget();
-}
-
-static void
-UpdateMirroringWidgetSync(nsMainThreadPtrHandle<nsScreenGonk>&& aScreen, nsWindow* aWindow)
-{
- MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
- already_AddRefed<nsWindow> window(aWindow);
- aScreen->UpdateMirroringWidget(window);
-}
-
-bool
-nsScreenGonk::EnableMirroring()
-{
- MOZ_ASSERT(NS_IsMainThread());
- MOZ_ASSERT(!IsPrimaryScreen());
-
- RefPtr<nsScreenGonk> primaryScreen = nsScreenManagerGonk::GetPrimaryScreen();
- NS_ENSURE_TRUE(primaryScreen, false);
-
- bool ret = primaryScreen->SetMirroringScreen(this);
- NS_ENSURE_TRUE(ret, false);
-
- // Create a widget for mirroring
- nsWidgetInitData initData;
- initData.mScreenId = mId;
- RefPtr<nsWindow> window = new nsWindow();
- nsresult rv = window->Create(nullptr, nullptr, mNaturalBounds, &initData);
- NS_ENSURE_SUCCESS(rv, false);
- MOZ_ASSERT(static_cast<nsWindow*>(window)->GetScreen() == this);
-
- // Update mMirroringWidget on compositor thread
- nsMainThreadPtrHandle<nsScreenGonk> primary =
- nsMainThreadPtrHandle<nsScreenGonk>(new nsMainThreadPtrHolder<nsScreenGonk>(primaryScreen, false));
- CompositorThreadHolder::Loop()->PostTask(
- NewRunnableFunction(&UpdateMirroringWidgetSync,
- primary,
- window.forget().take()));
-
- mIsMirroring = true;
- return true;
-}
-
-bool
-nsScreenGonk::DisableMirroring()
-{
- MOZ_ASSERT(NS_IsMainThread());
- MOZ_ASSERT(!IsPrimaryScreen());
-
- mIsMirroring = false;
- RefPtr<nsScreenGonk> primaryScreen = nsScreenManagerGonk::GetPrimaryScreen();
- NS_ENSURE_TRUE(primaryScreen, false);
-
- bool ret = primaryScreen->ClearMirroringScreen(this);
- NS_ENSURE_TRUE(ret, false);
-
- // Update mMirroringWidget on compositor thread
- nsMainThreadPtrHandle<nsScreenGonk> primary =
- nsMainThreadPtrHandle<nsScreenGonk>(new nsMainThreadPtrHolder<nsScreenGonk>(primaryScreen, false));
- CompositorThreadHolder::Loop()->PostTask(
- NewRunnableFunction(&UpdateMirroringWidgetSync,
- primary,
- nullptr));
- return true;
-}
-
-bool
-nsScreenGonk::SetMirroringScreen(nsScreenGonk* aScreen)
-{
- MOZ_ASSERT(NS_IsMainThread());
- MOZ_ASSERT(IsPrimaryScreen());
-
- if (mMirroringScreen) {
- return false;
- }
- mMirroringScreen = aScreen;
- return true;
-}
-
-bool
-nsScreenGonk::ClearMirroringScreen(nsScreenGonk* aScreen)
-{
- MOZ_ASSERT(NS_IsMainThread());
- MOZ_ASSERT(IsPrimaryScreen());
-
- if (mMirroringScreen != aScreen) {
- return false;
- }
- mMirroringScreen = nullptr;
- return true;
-}
-
-void
-nsScreenGonk::UpdateMirroringWidget(already_AddRefed<nsWindow>& aWindow)
-{
- MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
- MOZ_ASSERT(IsPrimaryScreen());
-
- if (mMirroringWidget) {
- nsCOMPtr<nsIWidget> widget = mMirroringWidget.forget();
- NS_ReleaseOnMainThread(widget.forget());
- }
- mMirroringWidget = aWindow;
-}
-
-nsWindow*
-nsScreenGonk::GetMirroringWidget()
-{
- MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
- MOZ_ASSERT(IsPrimaryScreen());
-
- return mMirroringWidget;
-}
-
-NS_IMPL_ISUPPORTS(nsScreenManagerGonk, nsIScreenManager)
-
-nsScreenManagerGonk::nsScreenManagerGonk()
- : mInitialized(false)
-#if ANDROID_VERSION >= 19
- , mDisplayEnabled(false)
-#endif
-{
-}
-
-nsScreenManagerGonk::~nsScreenManagerGonk()
-{
-}
-
-static StaticRefPtr<nsScreenManagerGonk> sScreenManagerGonk;
-
-/* static */ already_AddRefed<nsScreenManagerGonk>
-nsScreenManagerGonk::GetInstance()
-{
- MOZ_ASSERT(NS_IsMainThread());
-
- // Avoid creating nsScreenManagerGonk from content process.
- if (!XRE_IsParentProcess()) {
- MOZ_CRASH("Non-chrome processes should not get here.");
- }
-
- // Avoid creating multiple nsScreenManagerGonk instance inside main process.
- if (!sScreenManagerGonk) {
- sScreenManagerGonk = new nsScreenManagerGonk();
- ClearOnShutdown(&sScreenManagerGonk);
- }
-
- RefPtr<nsScreenManagerGonk> screenMgr = sScreenManagerGonk.get();
- return screenMgr.forget();
-}
-
-/* static */ already_AddRefed< nsScreenGonk>
-nsScreenManagerGonk::GetPrimaryScreen()
-{
- MOZ_ASSERT(NS_IsMainThread());
-
- RefPtr<nsScreenManagerGonk> manager = nsScreenManagerGonk::GetInstance();
- nsCOMPtr<nsIScreen> screen;
- manager->GetPrimaryScreen(getter_AddRefs(screen));
- MOZ_ASSERT(screen);
- return already_AddRefed<nsScreenGonk>(
- static_cast<nsScreenGonk*>(screen.forget().take()));
-}
-
-void
-nsScreenManagerGonk::Initialize()
-{
- if (mInitialized) {
- return;
- }
-
- mScreenOnEvent = new ScreenOnOffEvent(true);
- mScreenOffEvent = new ScreenOnOffEvent(false);
- GetGonkDisplay()->OnEnabled(displayEnabledCallback);
-
- AddScreen(GonkDisplay::DISPLAY_PRIMARY);
-
- nsAppShell::NotifyScreenInitialized();
- mInitialized = true;
-}
-
-void
-nsScreenManagerGonk::DisplayEnabled(bool aEnabled)
-{
- MOZ_ASSERT(NS_IsMainThread());
-
-#if ANDROID_VERSION >= 19
- /* Bug 1244044
- * This function could be called before |mCompositorVsyncScheduler| is set.
- * To avoid this issue, keep the value stored in |mDisplayEnabled|.
- */
- mDisplayEnabled = aEnabled;
- if (mCompositorVsyncScheduler) {
- mCompositorVsyncScheduler->SetDisplay(mDisplayEnabled);
- }
-#endif
-
- VsyncControl(aEnabled);
- NS_DispatchToMainThread(aEnabled ? mScreenOnEvent : mScreenOffEvent);
-}
-
-NS_IMETHODIMP
-nsScreenManagerGonk::GetPrimaryScreen(nsIScreen **outScreen)
-{
- NS_IF_ADDREF(*outScreen = mScreens[0].get());
- return NS_OK;
-}
-
-NS_IMETHODIMP
-nsScreenManagerGonk::ScreenForId(uint32_t aId,
- nsIScreen **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
-nsScreenManagerGonk::ScreenForRect(int32_t inLeft,
- int32_t inTop,
- int32_t inWidth,
- 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)
-{
- 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 = mScreens.Length();
- return NS_OK;
-}
-
-NS_IMETHODIMP
-nsScreenManagerGonk::GetSystemDefaultScale(float *aDefaultScale)
-{
- *aDefaultScale = 1.0f;
- return NS_OK;
-}
-
-void
-nsScreenManagerGonk::VsyncControl(bool aEnabled)
-{
- if (!NS_IsMainThread()) {
- NS_DispatchToMainThread(
- NewRunnableMethod<bool>(this,
- &nsScreenManagerGonk::VsyncControl,
- aEnabled));
- return;
- }
-
- MOZ_ASSERT(NS_IsMainThread());
- VsyncSource::Display &display = gfxPlatform::GetPlatform()->GetHardwareVsync()->GetGlobalDisplay();
- if (aEnabled) {
- display.EnableVsync();
- } else {
- display.DisableVsync();
- }
-}
-
-uint32_t
-nsScreenManagerGonk::GetIdFromType(GonkDisplay::DisplayType 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;
-}
-
-bool
-nsScreenManagerGonk::IsScreenConnected(uint32_t aId)
-{
- for (size_t i = 0; i < mScreens.Length(); ++i) {
- if (mScreens[i]->GetId() == aId) {
- return true;
- }
- }
-
- return false;
-}
-
-namespace {
-
-// A concrete class as a subject for 'display-changed' observer event.
-class DisplayInfo : public nsIDisplayInfo {
-public:
- NS_DECL_ISUPPORTS
-
- DisplayInfo(uint32_t aId, bool aConnected)
- : mId(aId)
- , mConnected(aConnected)
- {
- }
-
- NS_IMETHODIMP GetId(int32_t *aId)
- {
- *aId = mId;
- return NS_OK;
- }
-
- NS_IMETHODIMP GetConnected(bool *aConnected)
- {
- *aConnected = mConnected;
- return NS_OK;
- }
-
-private:
- virtual ~DisplayInfo() {}
-
- uint32_t mId;
- bool mConnected;
-};
-
-NS_IMPL_ISUPPORTS(DisplayInfo, nsIDisplayInfo, nsISupports)
-
-class NotifyTask : public mozilla::Runnable {
-public:
- NotifyTask(uint32_t aId, bool aConnected)
- : mDisplayInfo(new DisplayInfo(aId, aConnected))
- {
- }
-
- NS_IMETHOD Run() override
- {
- nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
- if (os) {
- os->NotifyObservers(mDisplayInfo, "display-changed", nullptr);
- }
-
- return NS_OK;
- }
-private:
- RefPtr<DisplayInfo> mDisplayInfo;
-};
-
-void
-NotifyDisplayChange(uint32_t aId, bool aConnected)
-{
- NS_DispatchToMainThread(new NotifyTask(aId, aConnected));
-}
-
-} // end of unnamed namespace.
-
-nsresult
-nsScreenManagerGonk::AddScreen(GonkDisplay::DisplayType aDisplayType,
- android::IGraphicBufferProducer* aSink,
- NotifyDisplayChangedEvent aEventVisibility)
-{
- MOZ_ASSERT(NS_IsMainThread());
-
- NS_ENSURE_TRUE(aDisplayType < GonkDisplay::DisplayType::NUM_DISPLAY_TYPES,
- NS_ERROR_FAILURE);
-
- uint32_t id = GetIdFromType(aDisplayType);
- NS_ENSURE_TRUE(!IsScreenConnected(id), NS_ERROR_FAILURE);
-
- GonkDisplay::NativeData nativeData =
- GetGonkDisplay()->GetNativeData(aDisplayType, aSink);
- nsScreenGonk* screen = new nsScreenGonk(id,
- aDisplayType,
- nativeData,
- aEventVisibility);
- mScreens.AppendElement(screen);
-
- if (aEventVisibility == NotifyDisplayChangedEvent::Observable) {
- NotifyDisplayChange(id, true);
- }
-
- // By default, non primary screen does mirroring.
- if (aDisplayType != GonkDisplay::DISPLAY_PRIMARY &&
- gfxPrefs::ScreenMirroringEnabled()) {
- screen->EnableMirroring();
- }
-
- return NS_OK;
-}
-
-nsresult
-nsScreenManagerGonk::RemoveScreen(GonkDisplay::DisplayType aDisplayType)
-{
- MOZ_ASSERT(NS_IsMainThread());
-
- NS_ENSURE_TRUE(aDisplayType < GonkDisplay::DisplayType::NUM_DISPLAY_TYPES,
- NS_ERROR_FAILURE);
-
- NotifyDisplayChangedEvent eventVisibility = NotifyDisplayChangedEvent::Observable;
- uint32_t screenId = GetIdFromType(aDisplayType);
- NS_ENSURE_TRUE(IsScreenConnected(screenId), NS_ERROR_FAILURE);
-
- for (size_t i = 0; i < mScreens.Length(); i++) {
- if (mScreens[i]->GetId() == screenId) {
- if (mScreens[i]->IsMirroring()) {
- mScreens[i]->DisableMirroring();
- }
- eventVisibility = mScreens[i]->GetEventVisibility();
- mScreens.RemoveElementAt(i);
- break;
- }
- }
-
- if (eventVisibility == NotifyDisplayChangedEvent::Observable) {
- NotifyDisplayChange(screenId, false);
- }
- return NS_OK;
-}
-
-#if ANDROID_VERSION >= 19
-void
-nsScreenManagerGonk::SetCompositorVsyncScheduler(mozilla::layers::CompositorVsyncScheduler *aObserver)
-{
- MOZ_ASSERT(NS_IsMainThread());
-
- // We assume on b2g that there is only 1 CompositorBridgeParent
- MOZ_ASSERT(mCompositorVsyncScheduler == nullptr);
- MOZ_ASSERT(aObserver);
- mCompositorVsyncScheduler = aObserver;
- mCompositorVsyncScheduler->SetDisplay(mDisplayEnabled);
-}
-#endif