From 33cf283e29529f90536c6529151df6e1a9d77420 Mon Sep 17 00:00:00 2001 From: Shelly Lin Date: Fri, 5 Jun 2015 11:29:30 +0800 Subject: [PATCH] Bug 1138287 - Part 2: Support multi-screen on Gonk platform. r=mwu, r=sotaro, r=jgilbert, r=mattwoodrow --- gfx/gl/GLContextProviderEGL.cpp | 23 +- .../composite/LayerManagerComposite.cpp | 5 +- gfx/layers/opengl/Composer2D.h | 7 +- gfx/layers/opengl/CompositorOGL.cpp | 7 +- widget/gonk/HwcComposer2D.cpp | 106 ++++++--- widget/gonk/HwcComposer2D.h | 19 +- widget/gonk/libdisplay/GonkDisplay.h | 46 ++-- widget/gonk/libdisplay/GonkDisplayICS.cpp | 23 +- widget/gonk/libdisplay/GonkDisplayICS.h | 15 +- widget/gonk/libdisplay/GonkDisplayJB.cpp | 101 +++++---- widget/gonk/libdisplay/GonkDisplayJB.h | 16 +- widget/gonk/nsScreenManagerGonk.cpp | 203 +++++++++++++++--- widget/gonk/nsScreenManagerGonk.h | 59 +++-- widget/gonk/nsWindow.cpp | 19 +- widget/gonk/nsWindow.h | 2 + widget/moz.build | 1 + widget/nsIDisplayInfo.idl | 14 ++ 17 files changed, 480 insertions(+), 186 deletions(-) create mode 100644 widget/nsIDisplayInfo.idl diff --git a/gfx/gl/GLContextProviderEGL.cpp b/gfx/gl/GLContextProviderEGL.cpp index 812d96587f8..4a424ede615 100644 --- a/gfx/gl/GLContextProviderEGL.cpp +++ b/gfx/gl/GLContextProviderEGL.cpp @@ -19,6 +19,8 @@ #define GET_NATIVE_WINDOW(aWidget) ((EGLNativeWindowType)aWidget->GetNativeData(NS_NATIVE_WINDOW)) #include "HwcComposer2D.h" #include "libdisplay/GonkDisplay.h" +#include "nsWindow.h" +#include "nsScreenManagerGonk.h" #endif #if defined(ANDROID) @@ -128,7 +130,7 @@ namespace gl { } while (0) static bool -CreateConfig(EGLConfig* aConfig); +CreateConfig(EGLConfig* aConfig, nsIWidget* aWidget); // append three zeros at the end of attribs list to work around // EGL implementation bugs that iterate until they find 0, instead of @@ -483,7 +485,7 @@ GLContextEGL::CreateSurfaceForWindow(nsIWidget* aWidget) } EGLConfig config; - if (!CreateConfig(&config)) { + if (!CreateConfig(&config, aWidget)) { MOZ_CRASH("Failed to create EGLConfig!\n"); return nullptr; } @@ -637,7 +639,7 @@ static const EGLint kEGLConfigAttribsRGBA32[] = { }; static bool -CreateConfig(EGLConfig* aConfig, int32_t depth) +CreateConfig(EGLConfig* aConfig, int32_t depth, nsIWidget* aWidget) { EGLConfig configs[64]; const EGLint* attribs; @@ -673,12 +675,13 @@ CreateConfig(EGLConfig* aConfig, int32_t depth) // HAL_PIXEL_FORMAT_RGBX_8888 // HAL_PIXEL_FORMAT_BGRA_8888 // HAL_PIXEL_FORMAT_RGB_565 + nsWindow* window = static_cast(aWidget); for (int j = 0; j < ncfg; ++j) { EGLConfig config = configs[j]; EGLint format; if (sEGLLibrary.fGetConfigAttrib(EGL_DISPLAY(), config, LOCAL_EGL_NATIVE_VISUAL_ID, &format) && - format == GetGonkDisplay()->surfaceformat) + format == window->GetScreen()->GetSurfaceFormat()) { *aConfig = config; return true; @@ -714,20 +717,20 @@ CreateConfig(EGLConfig* aConfig, int32_t depth) // NB: It's entirely legal for the returned EGLConfig to be valid yet // have the value null. static bool -CreateConfig(EGLConfig* aConfig) +CreateConfig(EGLConfig* aConfig, nsIWidget* aWidget) { int32_t depth = gfxPlatform::GetPlatform()->GetScreenDepth(); - if (!CreateConfig(aConfig, depth)) { + if (!CreateConfig(aConfig, depth, aWidget)) { #ifdef MOZ_WIDGET_ANDROID // Bug 736005 // Android doesn't always support 16 bit so also try 24 bit if (depth == 16) { - return CreateConfig(aConfig, 24); + return CreateConfig(aConfig, 24, aWidget); } // Bug 970096 // Some devices that have 24 bit screens only support 16 bit OpenGL? if (depth == 24) { - return CreateConfig(aConfig, 16); + return CreateConfig(aConfig, 16, aWidget); } #endif return false; @@ -772,7 +775,7 @@ GLContextProviderEGL::CreateForWindow(nsIWidget *aWidget) bool doubleBuffered = true; EGLConfig config; - if (!CreateConfig(&config)) { + if (!CreateConfig(&config, aWidget)) { MOZ_CRASH("Failed to create EGLConfig!\n"); return nullptr; } @@ -811,7 +814,7 @@ GLContextProviderEGL::CreateEGLSurface(void* aWindow) } EGLConfig config; - if (!CreateConfig(&config)) { + if (!CreateConfig(&config, static_cast(aWindow))) { MOZ_CRASH("Failed to create EGLConfig!\n"); } diff --git a/gfx/layers/composite/LayerManagerComposite.cpp b/gfx/layers/composite/LayerManagerComposite.cpp index b4811fb385a..99331ca8b69 100644 --- a/gfx/layers/composite/LayerManagerComposite.cpp +++ b/gfx/layers/composite/LayerManagerComposite.cpp @@ -666,7 +666,8 @@ LayerManagerComposite::Render() // We can't use composert2D if we have layer effects if (!mTarget && !haveLayerEffects && gfxPrefs::Composer2DCompositionEnabled() && - composer2D && composer2D->HasHwc() && composer2D->TryRenderWithHwc(mRoot, mGeometryChanged)) + composer2D && composer2D->HasHwc() && composer2D->TryRenderWithHwc(mRoot, + mCompositor->GetWidget(), mGeometryChanged)) { LayerScope::SetHWComposed(); if (mFPS) { @@ -772,7 +773,7 @@ LayerManagerComposite::Render() } if (composer2D) { - composer2D->Render(); + composer2D->Render(mCompositor->GetWidget()); } mCompositor->GetWidget()->PostRender(this); diff --git a/gfx/layers/opengl/Composer2D.h b/gfx/layers/opengl/Composer2D.h index 78c34c4befd..457742825d5 100644 --- a/gfx/layers/opengl/Composer2D.h +++ b/gfx/layers/opengl/Composer2D.h @@ -26,6 +26,8 @@ * layer manager fall back on full GPU composition. */ +class nsIWidget; + namespace mozilla { namespace layers { @@ -47,13 +49,14 @@ public: * Currently, when TryRender() returns true, the entire framebuffer * must have been rendered. */ - virtual bool TryRenderWithHwc(Layer* aRoot, bool aGeometryChanged) = 0; + virtual bool TryRenderWithHwc(Layer* aRoot, nsIWidget* aWidget, + bool aGeometryChanged) = 0; /** * Return true if Composer2D does composition. Return false if Composer2D * failed the composition. */ - virtual bool Render() = 0; + virtual bool Render(nsIWidget* aWidget) = 0; /** * Return true if Composer2D has a fast composition hardware. diff --git a/gfx/layers/opengl/CompositorOGL.cpp b/gfx/layers/opengl/CompositorOGL.cpp index e0d46fbdcd8..d592b535270 100644 --- a/gfx/layers/opengl/CompositorOGL.cpp +++ b/gfx/layers/opengl/CompositorOGL.cpp @@ -57,6 +57,8 @@ #if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17 #include "libdisplay/GonkDisplay.h" // for GonkDisplay #include +#include "nsWindow.h" +#include "nsScreenManagerGonk.h" #endif namespace mozilla { @@ -1401,8 +1403,9 @@ CompositorOGL::SetDispAcquireFence(Layer* aLayer) if (!aLayer) { return; } - - RefPtr fence = new FenceHandle::FdObj(GetGonkDisplay()->GetPrevDispAcquireFd()); + nsWindow* window = static_cast(mWidget); + RefPtr fence = new FenceHandle::FdObj( + window->GetScreen()->GetPrevDispAcquireFd()); mReleaseFenceHandle.Merge(FenceHandle(fence)); } diff --git a/widget/gonk/HwcComposer2D.cpp b/widget/gonk/HwcComposer2D.cpp index 496770bcfce..812e5c842be 100644 --- a/widget/gonk/HwcComposer2D.cpp +++ b/widget/gonk/HwcComposer2D.cpp @@ -33,6 +33,8 @@ #include "gfx2DGlue.h" #include "gfxPlatform.h" #include "VsyncSource.h" +#include "nsScreenManagerGonk.h" +#include "nsWindow.h" #if ANDROID_VERSION >= 17 #include "libdisplay/DisplaySurface.h" @@ -96,7 +98,7 @@ static void HookHotplug(const struct hwc_procs* aProcs, int aDisplay, int aConnected) { - // no op + HwcComposer2D::GetInstance()->Hotplug(aDisplay, aConnected); } static const hwc_procs_t sHWCProcs = { @@ -111,9 +113,6 @@ static StaticRefPtr sInstance; HwcComposer2D::HwcComposer2D() : mHwc(nullptr) , mList(nullptr) - , mDpy(EGL_NO_DISPLAY) - , mSur(EGL_NO_SURFACE) - , mGLContext(nullptr) , mMaxLayerCount(0) , mColorFill(false) , mRBSwapSupport(false) @@ -133,7 +132,8 @@ HwcComposer2D::HwcComposer2D() nsIntSize screenSize; - ANativeWindow *win = GetGonkDisplay()->GetNativeWindow(); + GonkDisplay::NativeData data = GetGonkDisplay()->GetNativeData(GonkDisplay::DISPLAY_PRIMARY); + ANativeWindow *win = data.mNativeWindow.get(); win->query(win, NATIVE_WINDOW_WIDTH, &screenSize.width); win->query(win, NATIVE_WINDOW_HEIGHT, &screenSize.height); mScreenRect = gfx::IntRect(gfx::IntPoint(0, 0), screenSize); @@ -248,6 +248,38 @@ HwcComposer2D::Invalidate() mCompositorParent->ScheduleRenderOnCompositorThread(); } } + +namespace { +class HotplugEvent : public nsRunnable { +public: + HotplugEvent(GonkDisplay::DisplayType aType, bool aConnected) + : mType(aType) + , mConnected(aConnected) + { + } + + NS_IMETHOD Run() + { + nsRefPtr screenManager = + nsScreenManagerGonk::GetInstance(); + if (mConnected) { + screenManager->AddScreen(mType); + } else { + screenManager->RemoveScreen(mType); + } + } +private: + GonkDisplay::DisplayType mType; + bool mConnected; +}; +} // anonymous namespace + +void +HwcComposer2D::Hotplug(int aDisplay, int aConnected) +{ + NS_DispatchToMainThread(new HotplugEvent(GonkDisplay::DISPLAY_EXTERNAL, + aConnected)); +} #endif void @@ -257,14 +289,6 @@ HwcComposer2D::SetCompositorParent(CompositorParent* aCompositorParent) mCompositorParent = aCompositorParent; } -void -HwcComposer2D::SetEGLInfo(hwc_display_t aDisplay, hwc_surface_t aSurface, gl::GLContext* aGLContext) -{ - mDpy = aDisplay; - mSur = aSurface; - mGLContext = aGLContext; -} - bool HwcComposer2D::ReallocLayerList() { @@ -684,9 +708,9 @@ HwcComposer2D::PrepareLayerList(Layer* aLayer, #if ANDROID_VERSION >= 17 bool -HwcComposer2D::TryHwComposition() +HwcComposer2D::TryHwComposition(nsScreenGonk* aScreen) { - DisplaySurface* dispSurface = (DisplaySurface*)(GetGonkDisplay()->GetDispSurface()); + DisplaySurface* dispSurface = aScreen->GetDisplaySurface(); if (!(dispSurface && dispSurface->lastHandle)) { LOGD("H/W Composition failed. DispSurface not initialized."); @@ -702,7 +726,7 @@ HwcComposer2D::TryHwComposition() } } - Prepare(dispSurface->lastHandle, -1); + Prepare(dispSurface->lastHandle, -1, aScreen); /* Possible composition paths, after hwc prepare: 1. GPU Composition @@ -757,8 +781,8 @@ HwcComposer2D::TryHwComposition() return false; } else if (blitComposite) { // BLIT Composition, flip DispSurface target - GetGonkDisplay()->UpdateDispSurface(mDpy, mSur); - DisplaySurface* dispSurface = (DisplaySurface*)(GetGonkDisplay()->GetDispSurface()); + GetGonkDisplay()->UpdateDispSurface(aScreen->GetDpy(), aScreen->GetSur()); + DisplaySurface* dispSurface = aScreen->GetDisplaySurface(); if (!dispSurface) { LOGE("H/W Composition failed. NULL DispSurface."); return false; @@ -769,22 +793,25 @@ HwcComposer2D::TryHwComposition() } // BLIT or full OVERLAY Composition - Commit(); + Commit(aScreen); - GetGonkDisplay()->SetDispReleaseFd(mList->hwLayers[idx].releaseFenceFd); + DisplaySurface* displaySurface = aScreen->GetDisplaySurface(); + displaySurface->setReleaseFenceFd(mList->hwLayers[idx].releaseFenceFd); mList->hwLayers[idx].releaseFenceFd = -1; return true; } bool -HwcComposer2D::Render() +HwcComposer2D::Render(nsIWidget* aWidget) { + nsScreenGonk* screen = static_cast(aWidget)->GetScreen(); + // HWC module does not exist or mList is not created yet. if (!mHwc || !mList) { - return GetGonkDisplay()->SwapBuffers(mDpy, mSur); + return GetGonkDisplay()->SwapBuffers(screen->GetDpy(), screen->GetSur()); } - DisplaySurface* dispSurface = (DisplaySurface*)(GetGonkDisplay()->GetDispSurface()); + DisplaySurface* dispSurface = screen->GetDisplaySurface(); if (!dispSurface) { LOGE("H/W Composition failed. DispSurface not initialized."); return false; @@ -804,25 +831,26 @@ HwcComposer2D::Render() mList->hwLayers[0].acquireFenceFd = -1; mList->hwLayers[0].releaseFenceFd = -1; mList->hwLayers[0].displayFrame = {0, 0, mScreenRect.width, mScreenRect.height}; - Prepare(dispSurface->lastHandle, dispSurface->GetPrevDispAcquireFd()); + Prepare(dispSurface->lastHandle, dispSurface->GetPrevDispAcquireFd(), screen); } // GPU or partial HWC Composition - Commit(); + Commit(screen); - GetGonkDisplay()->SetDispReleaseFd(mList->hwLayers[mList->numHwLayers - 1].releaseFenceFd); + dispSurface->setReleaseFenceFd(mList->hwLayers[mList->numHwLayers - 1].releaseFenceFd); mList->hwLayers[mList->numHwLayers - 1].releaseFenceFd = -1; return true; } void -HwcComposer2D::Prepare(buffer_handle_t dispHandle, int fence) +HwcComposer2D::Prepare(buffer_handle_t dispHandle, int fence, nsScreenGonk* screen) { int idx = mList->numHwLayers - 1; const hwc_rect_t r = {0, 0, mScreenRect.width, mScreenRect.height}; hwc_display_contents_1_t *displays[HWC_NUM_DISPLAY_TYPES] = { nullptr }; - displays[HWC_DISPLAY_PRIMARY] = mList; + uint32_t displaytype = screen->GetDisplayType(); + displays[displaytype] = mList; mList->outbufAcquireFenceFd = -1; mList->outbuf = nullptr; mList->retireFenceFd = -1; @@ -845,15 +873,17 @@ HwcComposer2D::Prepare(buffer_handle_t dispHandle, int fence) if (mPrepared) { LOGE("Multiple hwc prepare calls!"); } + mHwc->prepare(mHwc, HWC_NUM_DISPLAY_TYPES, displays); mPrepared = true; } bool -HwcComposer2D::Commit() +HwcComposer2D::Commit(nsScreenGonk* aScreen) { hwc_display_contents_1_t *displays[HWC_NUM_DISPLAY_TYPES] = { nullptr }; - displays[HWC_DISPLAY_PRIMARY] = mList; + uint32_t displaytype = aScreen->GetDisplayType(); + displays[displaytype] = mList; for (uint32_t j=0; j < (mList->numHwLayers - 1); j++) { mList->hwLayers[j].acquireFenceFd = -1; @@ -910,15 +940,17 @@ HwcComposer2D::Reset() } #else bool -HwcComposer2D::TryHwComposition() +HwcComposer2D::TryHwComposition(nsScreenGonk* aScreen) { - return !mHwc->set(mHwc, mDpy, mSur, mList); + return !mHwc->set(mHwc, aScreen->GetDpy(), aScreen->GetSur(), mList); } bool -HwcComposer2D::Render() +HwcComposer2D::Render(nsIWidget* aWidget) { - return GetGonkDisplay()->SwapBuffers(mDpy, mSur); + nsScreenGonk* screen = static_cast(aWidget)->GetScreen(); + + return GetGonkDisplay()->SwapBuffers(screen->GetDpy(), screen->GetSur()); } void @@ -930,12 +962,15 @@ HwcComposer2D::Reset() bool HwcComposer2D::TryRenderWithHwc(Layer* aRoot, + nsIWidget* aWidget, bool aGeometryChanged) { if (!mHwc) { return false; } + nsScreenGonk* screen = static_cast(aWidget)->GetScreen(); + if (mList) { setHwcGeometry(aGeometryChanged); mList->numHwLayers = 0; @@ -950,6 +985,7 @@ HwcComposer2D::TryRenderWithHwc(Layer* aRoot, // reallocated. We may want to avoid this if possible mVisibleRegions.clear(); + mScreenRect = screen->GetNaturalBounds(); MOZ_ASSERT(mHwcLayerMap.IsEmpty()); if (!PrepareLayerList(aRoot, mScreenRect, @@ -963,7 +999,7 @@ HwcComposer2D::TryRenderWithHwc(Layer* aRoot, // Send data to LayerScope for debugging SendtoLayerScope(); - if (!TryHwComposition()) { + if (!TryHwComposition(screen)) { LOGD("Full HWC Composition failed. Fallback to GPU Composition or partial OVERLAY Composition"); LayerScope::CleanLayer(); return false; diff --git a/widget/gonk/HwcComposer2D.h b/widget/gonk/HwcComposer2D.h index e9141cf030c..08b0c6c74ad 100644 --- a/widget/gonk/HwcComposer2D.h +++ b/widget/gonk/HwcComposer2D.h @@ -31,6 +31,8 @@ #include #endif +class nsScreenGonk; + namespace mozilla { namespace gl { @@ -83,9 +85,10 @@ public: // Returns FALSE if the container cannot be fully rendered // by this composer so nothing was rendered at all virtual bool TryRenderWithHwc(layers::Layer* aRoot, + nsIWidget* aWidget, bool aGeometryChanged) override; - virtual bool Render() override; + virtual bool Render(nsIWidget* aWidget) override; virtual bool HasHwc() override { return mHwc; } @@ -94,18 +97,15 @@ public: bool RegisterHwcEventCallback(); void Vsync(int aDisplay, int64_t aTimestamp); void Invalidate(); + void Hotplug(int aDisplay, int aConnected); #endif void SetCompositorParent(layers::CompositorParent* aCompositorParent); - // Set EGL info of primary display. Used for BLIT Composition. - // XXX Add multiple displays compostion support. - void SetEGLInfo(hwc_display_t aDisplay, hwc_surface_t aSurface, gl::GLContext* aGLContext); - private: void Reset(); - void Prepare(buffer_handle_t dispHandle, int fence); - bool Commit(); - bool TryHwComposition(); + void Prepare(buffer_handle_t dispHandle, int fence, nsScreenGonk* screen); + bool Commit(nsScreenGonk* aScreen); + bool TryHwComposition(nsScreenGonk* aScreen); bool ReallocLayerList(); bool PrepareLayerList(layers::Layer* aContainer, const nsIntRect& aClip, const gfx::Matrix& aParentTransform); @@ -115,9 +115,6 @@ private: HwcDevice* mHwc; HwcList* mList; - hwc_display_t mDpy; // Store for BLIT Composition and GonkDisplayICS - hwc_surface_t mSur; // Store for BLIT Composition and GonkDisplayICS - gl::GLContext* mGLContext; // Store for BLIT Composition nsIntRect mScreenRect; int mMaxLayerCount; bool mColorFill; diff --git a/widget/gonk/libdisplay/GonkDisplay.h b/widget/gonk/libdisplay/GonkDisplay.h index 8f50ee768ea..0f703e7450f 100644 --- a/widget/gonk/libdisplay/GonkDisplay.h +++ b/widget/gonk/libdisplay/GonkDisplay.h @@ -17,8 +17,14 @@ #define GONKDISPLAY_H #include +#include #include "mozilla/Types.h" +namespace android { +class DisplaySurface; +class IGraphicBufferProducer; +} + namespace mozilla { typedef void * EGLDisplay; @@ -26,7 +32,28 @@ typedef void * EGLSurface; class MOZ_EXPORT GonkDisplay { public: - virtual ANativeWindow* GetNativeWindow() = 0; + /** + * This enum is for types of display. DISPLAY_PRIMARY refers to the default + * built-in display, DISPLAY_EXTERNAL refers to displays connected with + * HDMI, and DISPLAY_VIRTUAL are displays which makes composited output + * available within the system. Currently, displays of external are detected + * via the hotplug detection in HWC, and displays of virtual are connected + * via Wifi Display. + */ + enum DisplayType { + DISPLAY_PRIMARY, + DISPLAY_EXTERNAL, + DISPLAY_VIRTUAL, + NUM_DISPLAY_TYPES + }; + + struct NativeData { + android::sp mNativeWindow; +#if ANDROID_VERSION >= 17 + android::sp mDisplaySurface; +#endif + float mXdpi; + }; virtual void SetEnabled(bool enabled) = 0; @@ -36,8 +63,6 @@ public: virtual void* GetHWCDevice() = 0; - virtual void* GetDispSurface() = 0; - /** * Only GonkDisplayICS uses arguments. */ @@ -49,18 +74,9 @@ public: virtual void UpdateDispSurface(EGLDisplay dpy, EGLSurface sur) = 0; - /** - * Set FramebufferSurface ReleaseFence's file descriptor. - * ReleaseFence will be signaled after the HWC has finished reading - * from a buffer. - */ - virtual void SetDispReleaseFd(int fd) = 0; - - /** - * Get FramebufferSurface AcquireFence's file descriptor - * AcquireFence will be signaled when a buffer's content is available. - */ - virtual int GetPrevDispAcquireFd() = 0; + virtual NativeData GetNativeData( + GonkDisplay::DisplayType aDisplayType, + android::IGraphicBufferProducer* aProducer = nullptr) = 0; float xdpi; int32_t surfaceformat; diff --git a/widget/gonk/libdisplay/GonkDisplayICS.cpp b/widget/gonk/libdisplay/GonkDisplayICS.cpp index 8c6efdf7eed..1dbc2b87b13 100644 --- a/widget/gonk/libdisplay/GonkDisplayICS.cpp +++ b/widget/gonk/libdisplay/GonkDisplayICS.cpp @@ -23,6 +23,7 @@ #include #include +#include "mozilla/Assertions.h" #include "mozilla/FileUtils.h" #include "mozilla/FileUtils.h" @@ -139,13 +140,6 @@ GonkDisplayICS::~GonkDisplayICS() hwc_close(mHwc); } -ANativeWindow* -GonkDisplayICS::GetNativeWindow() -{ - StopBootAnimation(); - return static_cast(mFBSurface.get()); -} - void GonkDisplayICS::SetEnabled(bool enabled) { @@ -207,7 +201,6 @@ GonkDisplayICS::QueueBuffer(ANativeWindowBuffer *buf) void GonkDisplayICS::UpdateDispSurface(EGLDisplay dpy, EGLSurface sur) { - eglSwapBuffers(dpy, sur); } void @@ -215,6 +208,20 @@ GonkDisplayICS::SetDispReleaseFd(int fd) { } +GonkDisplay::NativeData +GonkDisplayICS::GetNativeData(GonkDisplay::DisplayType aDisplayType, + android::IGraphicBufferProducer* aProducer) +{ + MOZ_ASSERT(aDisplayType == DISPLAY_PRIMARY, "ICS gonk supports primary display only."); + + NativeData data; + StopBootAnimation(); + data.mNativeWindow = static_cast(mFBSurface.get()); + data.mXdpi = xdpi; + + return data; +} + __attribute__ ((visibility ("default"))) GonkDisplay* GetGonkDisplay() diff --git a/widget/gonk/libdisplay/GonkDisplayICS.h b/widget/gonk/libdisplay/GonkDisplayICS.h index 8a6a0ff065a..e47ad2741c2 100644 --- a/widget/gonk/libdisplay/GonkDisplayICS.h +++ b/widget/gonk/libdisplay/GonkDisplayICS.h @@ -23,6 +23,10 @@ #include "hardware/hwcomposer.h" #include "utils/RefBase.h" +namespace android { +class IGraphicBufferProducer; +} + namespace mozilla { class MOZ_EXPORT GonkDisplayICS : public GonkDisplay { @@ -30,19 +34,12 @@ public: GonkDisplayICS(); ~GonkDisplayICS(); - virtual ANativeWindow* GetNativeWindow(); - virtual void SetEnabled(bool enabled); virtual void OnEnabled(OnEnabledCallbackType callback); virtual void* GetHWCDevice(); - virtual void* GetDispSurface() - { - return nullptr; - } - virtual bool SwapBuffers(EGLDisplay dpy, EGLSurface sur); virtual ANativeWindowBuffer* DequeueBuffer(); @@ -58,6 +55,10 @@ public: return -1; } + virtual NativeData GetNativeData( + GonkDisplay::DisplayType aDisplayType, + android::IGraphicBufferProducer* aProducer = nullptr); + private: hw_module_t const* mModule; hwc_composer_device_t* mHwc; diff --git a/widget/gonk/libdisplay/GonkDisplayJB.cpp b/widget/gonk/libdisplay/GonkDisplayJB.cpp index 2328ca66a7e..fcb7f740f1b 100644 --- a/widget/gonk/libdisplay/GonkDisplayJB.cpp +++ b/widget/gonk/libdisplay/GonkDisplayJB.cpp @@ -26,11 +26,14 @@ #include #include +#include "BootAnimation.h" #include "FramebufferSurface.h" #if ANDROID_VERSION == 17 #include "GraphicBufferAlloc.h" #endif -#include "BootAnimation.h" +#include "mozilla/Assertions.h" + +#define DEFAULT_XDPI 75.0 using namespace android; @@ -108,7 +111,7 @@ GonkDisplayJB::GonkDisplayJB() mAlloc = new GraphicBufferAlloc(); - CreateSurface(mSTClient, mDispSurface); + CreateSurface(mSTClient, mDispSurface, mWidth, mHeight); mList = (hwc_display_contents_1_t *)calloc(1, sizeof(*mList) + (sizeof(hwc_layer_1_t)*2)); @@ -118,18 +121,10 @@ GonkDisplayJB::GonkDisplayJB() mSTClient->perform(mSTClient.get(), NATIVE_WINDOW_SET_BUFFER_COUNT, 2); mSTClient->perform(mSTClient.get(), NATIVE_WINDOW_SET_USAGE, usage); } else if (mHwc) { -#if ANDROID_VERSION >= 21 - if (mHwc->common.version >= HWC_DEVICE_API_VERSION_1_4) { - mHwc->setPowerMode(mHwc, HWC_DISPLAY_PRIMARY, HWC_POWER_MODE_NORMAL); - } else { - mHwc->blank(mHwc, HWC_DISPLAY_PRIMARY, 0); - } -#else - mHwc->blank(mHwc, HWC_DISPLAY_PRIMARY, 0); -#endif + PowerOnDisplay(HWC_DISPLAY_PRIMARY); // For devices w/ hwc v1.0 or no hwc, this buffer can not be created, // only create this buffer for devices w/ hwc version > 1.0. - CreateSurface(mBootAnimSTClient, mBootAnimDispSurface); + CreateSurface(mBootAnimSTClient, mBootAnimDispSurface, mWidth, mHeight); } ALOGI("Starting bootanimation with (%d) format framebuffer", surfaceformat); @@ -147,7 +142,8 @@ GonkDisplayJB::~GonkDisplayJB() void GonkDisplayJB::CreateSurface(android::sp& aNativeWindow, - android::sp& aDisplaySurface) + android::sp& aDisplaySurface, + uint32_t aWidth, uint32_t aHeight) { #if ANDROID_VERSION >= 21 sp producer; @@ -163,7 +159,7 @@ GonkDisplayJB::CreateSurface(android::sp& aNativeWindow, sp consumer = new BufferQueue(true, mAlloc); #endif - aDisplaySurface = new FramebufferSurface(0, mWidth, mHeight, surfaceformat, consumer); + aDisplaySurface = new FramebufferSurface(0, aWidth, aHeight, surfaceformat, consumer); #if ANDROID_VERSION == 17 aNativeWindow = new SurfaceTextureClient( @@ -173,14 +169,6 @@ GonkDisplayJB::CreateSurface(android::sp& aNativeWindow, #endif } -ANativeWindow* -GonkDisplayJB::GetNativeWindow() -{ - StopBootAnim(); - - return mSTClient.get(); -} - void GonkDisplayJB::SetEnabled(bool enabled) { @@ -234,12 +222,6 @@ GonkDisplayJB::GetHWCDevice() return mHwc; } -void* -GonkDisplayJB::GetDispSurface() -{ - return mDispSurface.get(); -} - bool GonkDisplayJB::SwapBuffers(EGLDisplay dpy, EGLSurface sur) { @@ -363,18 +345,6 @@ GonkDisplayJB::UpdateDispSurface(EGLDisplay dpy, EGLSurface sur) eglSwapBuffers(dpy, sur); } -void -GonkDisplayJB::SetDispReleaseFd(int fd) -{ - mDispSurface->setReleaseFenceFd(fd); -} - -int -GonkDisplayJB::GetPrevDispAcquireFd() -{ - return mDispSurface->GetPrevDispAcquireFd(); -} - void GonkDisplayJB::StopBootAnim() { @@ -385,6 +355,57 @@ GonkDisplayJB::StopBootAnim() } } +void +GonkDisplayJB::PowerOnDisplay(int aDpy) +{ + MOZ_ASSERT(mHwc);; +#if ANDROID_VERSION >= 21 + if (mHwc->common.version >= HWC_DEVICE_API_VERSION_1_4) { + mHwc->setPowerMode(mHwc, aDpy, HWC_POWER_MODE_NORMAL); + } else { + mHwc->blank(mHwc, aDpy, 0); + } +#else + mHwc->blank(mHwc, aDpy, 0); +#endif +} + +GonkDisplay::NativeData +GonkDisplayJB::GetNativeData(GonkDisplay::DisplayType aDisplayType, + android::IGraphicBufferProducer* aProducer) +{ + NativeData data; + + if (aDisplayType == DISPLAY_PRIMARY) { + StopBootAnim(); + data.mNativeWindow = mSTClient; + data.mDisplaySurface = mDispSurface; + data.mXdpi = xdpi; + } else if (aDisplayType == DISPLAY_EXTERNAL) { + int32_t values[3]; + const uint32_t attrs[] = { + HWC_DISPLAY_WIDTH, + HWC_DISPLAY_HEIGHT, + HWC_DISPLAY_DPI_X, + HWC_DISPLAY_NO_ATTRIBUTE + }; + mHwc->getDisplayAttributes(mHwc, aDisplayType, 0, attrs, values); + int width = values[0]; + int height = values[1]; + // FIXME!! values[2] returns 0 for external display, which doesn't + // sound right, Bug 1169176 is the follow-up bug for this issue. + data.mXdpi = values[2] ? values[2] / 1000.f : DEFAULT_XDPI; + PowerOnDisplay(HWC_DISPLAY_EXTERNAL); + CreateSurface(data.mNativeWindow, data.mDisplaySurface, width, height); + } else if (aDisplayType == DISPLAY_VIRTUAL) { + // TODO: Bug 1161874 (the support of WifiDisplay) should fill up the + // implementation of virtual display. + MOZ_CRASH("Display type of virtual is not supported yet."); + } + + return data; +} + __attribute__ ((visibility ("default"))) GonkDisplay* GetGonkDisplay() diff --git a/widget/gonk/libdisplay/GonkDisplayJB.h b/widget/gonk/libdisplay/GonkDisplayJB.h index 0f9054492ac..d8ed9b4d37c 100644 --- a/widget/gonk/libdisplay/GonkDisplayJB.h +++ b/widget/gonk/libdisplay/GonkDisplayJB.h @@ -30,16 +30,12 @@ public: GonkDisplayJB(); ~GonkDisplayJB(); - virtual ANativeWindow* GetNativeWindow(); - virtual void SetEnabled(bool enabled); virtual void OnEnabled(OnEnabledCallbackType callback); virtual void* GetHWCDevice(); - virtual void* GetDispSurface(); - virtual bool SwapBuffers(EGLDisplay dpy, EGLSurface sur); virtual ANativeWindowBuffer* DequeueBuffer(); @@ -48,16 +44,18 @@ public: virtual void UpdateDispSurface(EGLDisplay dpy, EGLSurface sur); - virtual void SetDispReleaseFd(int fd); - - virtual int GetPrevDispAcquireFd(); - bool Post(buffer_handle_t buf, int fence); + virtual NativeData GetNativeData( + GonkDisplay::DisplayType aDisplayType, + android::IGraphicBufferProducer* aProducer = nullptr); + private: void StopBootAnim(); void CreateSurface(android::sp& aNativeWindow, - android::sp& aDisplaySurface); + android::sp& aDisplaySurface, + uint32_t aWidth, uint32_t aHeight); + void PowerOnDisplay(int aDpy); hw_module_t const* mModule; hw_module_t const* mFBModule; diff --git a/widget/gonk/nsScreenManagerGonk.cpp b/widget/gonk/nsScreenManagerGonk.cpp index 9b4fcedc0e5..45dd8eb1c87 100644 --- a/widget/gonk/nsScreenManagerGonk.cpp +++ b/widget/gonk/nsScreenManagerGonk.cpp @@ -19,7 +19,6 @@ #include "mozilla/TouchEvents.h" #include "mozilla/Hal.h" #include "libdisplay/GonkDisplay.h" -#include "libdisplay/DisplaySurface.h" #include "nsScreenManagerGonk.h" #include "nsThreadUtils.h" #include "HwcComposer2D.h" @@ -32,7 +31,11 @@ #include "nsAppShell.h" #include "nsTArray.h" #include "pixelflinger/format.h" -#include "cutils/properties.h" +#include "nsIDisplayInfo.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) @@ -103,16 +106,25 @@ SurfaceFormatToColorDepth(int32_t aSurfaceFormat) // nsScreenGonk.cpp -nsScreenGonk::nsScreenGonk(uint32_t aId, ANativeWindow* aNativeWindow) +nsScreenGonk::nsScreenGonk(uint32_t aId, + GonkDisplay::DisplayType aDisplayType, + const GonkDisplay::NativeData& aNativeData) : mId(aId) - , mNativeWindow(aNativeWindow) + , mNativeWindow(aNativeData.mNativeWindow) + , mDpi(aNativeData.mXdpi) , mScreenRotation(nsIScreen::ROTATION_0_DEG) , mPhysicalScreenRotation(nsIScreen::ROTATION_0_DEG) +#if ANDROID_VERSION >= 17 + , mDisplaySurface(aNativeData.mDisplaySurface) +#endif + , mDisplayType(aDisplayType) + , mDpy(EGL_NO_DISPLAY) + , mSur(EGL_NO_SURFACE) + , mGLContext(nullptr) { - 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)) { + mNativeWindow->query(mNativeWindow.get(), NATIVE_WINDOW_FORMAT, &mSurfaceFormat)) { NS_RUNTIMEABORT("Failed to get native window size, aborting..."); } @@ -124,8 +136,7 @@ nsScreenGonk::nsScreenGonk(uint32_t aId, ANativeWindow* aNativeWindow) mPhysicalScreenRotation = atoi(propValue) / 90; } - mDpi = GetGonkDisplay()->xdpi; - mColorDepth = SurfaceFormatToColorDepth(surfaceFormat); + mColorDepth = SurfaceFormatToColorDepth(mSurfaceFormat); } nsScreenGonk::~nsScreenGonk() @@ -135,7 +146,7 @@ nsScreenGonk::~nsScreenGonk() bool nsScreenGonk::IsPrimaryScreen() { - return nsScreenManagerGonk::PRIMARY_SCREEN_ID == mId; + return mDisplayType == GonkDisplay::DISPLAY_PRIMARY; } NS_IMETHODIMP @@ -206,6 +217,12 @@ nsScreenGonk::GetDpi() return mDpi; } +int32_t +nsScreenGonk::GetSurfaceFormat() +{ + return mSurfaceFormat; +} + ANativeWindow* nsScreenGonk::GetNativeWindow() { @@ -238,8 +255,8 @@ nsScreenGonk::SetRotation(uint32_t aRotation) for (unsigned int i = 0; i < mTopWindows.Length(); i++) { mTopWindows[i]->Resize(mVirtualBounds.width, - mVirtualBounds.height, - true); + mVirtualBounds.height, + true); } return NS_OK; @@ -314,6 +331,50 @@ nsScreenGonk::BringToTop(nsWindow* aWindow) mTopWindows.InsertElementAt(0, aWindow); } +#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) +{ + mDpy = aDisplay; + mSur = aSurface; + mGLContext = aGLContext; +} + +hwc_display_t +nsScreenGonk::GetDpy() +{ + return mDpy; +} + +hwc_surface_t +nsScreenGonk::GetSur() +{ + return mSur; +} + NS_IMPL_ISUPPORTS(nsScreenManagerGonk, nsIScreenManager) nsScreenManagerGonk::nsScreenManagerGonk() @@ -357,7 +418,7 @@ nsScreenManagerGonk::Initialize() mScreenOffEvent = new ScreenOnOffEvent(false); GetGonkDisplay()->OnEnabled(displayEnabledCallback); - AddScreen(PRIMARY_SCREEN_TYPE); + AddScreen(GonkDisplay::DISPLAY_PRIMARY); nsAppShell::NotifyScreenInitialized(); mInitialized = true; @@ -458,7 +519,7 @@ nsScreenManagerGonk::VsyncControl(bool aEnabled) } uint32_t -nsScreenManagerGonk::GetIdFromType(uint32_t aDisplayType) +nsScreenManagerGonk::GetIdFromType(GonkDisplay::DisplayType aDisplayType) { // This is the only place where we make the assumption that // display type is equivalent to screen id. @@ -467,28 +528,122 @@ nsScreenManagerGonk::GetIdFromType(uint32_t aDisplayType) return aDisplayType; } -void -nsScreenManagerGonk::AddScreen(uint32_t aDisplayType) +bool +nsScreenManagerGonk::IsScreenConnected(uint32_t aId) { - // We currently only support adding primary screen. - MOZ_ASSERT(PRIMARY_SCREEN_TYPE == aDisplayType); + for (size_t i = 0; i < mScreens.Length(); ++i) { + if (mScreens[i]->GetId() == aId) { + return true; + } + } - uint32_t id = GetIdFromType(aDisplayType); - - ANativeWindow* win = GetGonkDisplay()->GetNativeWindow(); - nsScreenGonk* screen = new nsScreenGonk(id, win); - - mScreens.AppendElement(screen); + 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 nsRunnable { +public: + NotifyTask(uint32_t aId, bool aConnected) + : mDisplayInfo(new DisplayInfo(aId, aConnected)) + { + } + + NS_IMETHOD Run() + { + nsCOMPtr os = mozilla::services::GetObserverService(); + if (os) { + os->NotifyObservers(mDisplayInfo, "display-changed", nullptr); + } + + return NS_OK; + } +private: + nsRefPtr mDisplayInfo; +}; + void -nsScreenManagerGonk::RemoveScreen(uint32_t aDisplayType) +NotifyDisplayChange(uint32_t aId, bool aConnected) { + NS_DispatchToMainThread(new NotifyTask(aId, aConnected)); +} + +} // end of unnamed namespace. + +nsresult +nsScreenManagerGonk::AddScreen(GonkDisplay::DisplayType aDisplayType, + android::IGraphicBufferProducer* aProducer) +{ + 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, aProducer); + nsScreenGonk* screen = new nsScreenGonk(id, aDisplayType, nativeData); + + mScreens.AppendElement(screen); + + NotifyDisplayChange(id, true); + + 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); + 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) { mScreens.RemoveElementAt(i); break; } } + + NotifyDisplayChange(screenId, false); + + return NS_OK; } diff --git a/widget/gonk/nsScreenManagerGonk.h b/widget/gonk/nsScreenManagerGonk.h index 9558a168a4f..49403919d9a 100644 --- a/widget/gonk/nsScreenManagerGonk.h +++ b/widget/gonk/nsScreenManagerGonk.h @@ -18,20 +18,37 @@ #define nsScreenManagerGonk_h___ #include "mozilla/Hal.h" -#include "nsCOMPtr.h" +#include "cutils/properties.h" +#include "hardware/hwcomposer.h" +#include "libdisplay/GonkDisplay.h" #include "nsBaseScreen.h" +#include "nsCOMPtr.h" #include "nsIScreenManager.h" class nsRunnable; class nsWindow; +namespace android { + class DisplaySurface; + class IGraphicBufferProducer; +}; + +namespace mozilla { +namespace gl { + class GLContext; +} +} + class nsScreenGonk : public nsBaseScreen { typedef mozilla::hal::ScreenConfiguration ScreenConfiguration; + typedef mozilla::GonkDisplay GonkDisplay; public: - nsScreenGonk(uint32_t aId, ANativeWindow* aNativeWindow); + nsScreenGonk(uint32_t aId, + GonkDisplay::DisplayType aDisplayType, + const GonkDisplay::NativeData& aNativeData); ~nsScreenGonk(); @@ -46,12 +63,19 @@ public: uint32_t GetId(); nsIntRect GetRect(); float GetDpi(); + int32_t GetSurfaceFormat(); ANativeWindow* GetNativeWindow(); nsIntRect GetNaturalBounds(); uint32_t EffectiveScreenRotation(); ScreenConfiguration GetConfiguration(); bool IsPrimaryScreen(); +#if ANDROID_VERSION >= 17 + android::DisplaySurface* GetDisplaySurface(); + int GetPrevDispAcquireFd(); +#endif + GonkDisplay::DisplayType GetDisplayType(); + void RegisterWindow(nsWindow* aWindow); void UnregisterWindow(nsWindow* aWindow); void BringToTop(nsWindow* aWindow); @@ -61,28 +85,36 @@ public: return mTopWindows; } + // Set EGL info of primary display. Used for BLIT Composition. + void SetEGLInfo(hwc_display_t aDisplay, hwc_surface_t aSurface, + mozilla::gl::GLContext* aGLContext); + hwc_display_t GetDpy(); + hwc_surface_t GetSur(); + protected: uint32_t mId; int32_t mColorDepth; android::sp mNativeWindow; float mDpi; + int32_t mSurfaceFormat; 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 mTopWindows; +#if ANDROID_VERSION >= 17 + android::sp mDisplaySurface; +#endif + GonkDisplay::DisplayType mDisplayType; + hwc_display_t mDpy; // Store for BLIT Composition and GonkDisplayICS + hwc_surface_t mSur; // Store for BLIT Composition and GonkDisplayICS + mozilla::gl::GLContext* mGLContext; // Store for BLIT Composition }; 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, - }; + typedef mozilla::GonkDisplay GonkDisplay; public: nsScreenManagerGonk(); @@ -96,13 +128,16 @@ public: void Initialize(); void DisplayEnabled(bool aEnabled); - void AddScreen(uint32_t aDisplayType); - void RemoveScreen(uint32_t aDisplayType); + nsresult AddScreen(GonkDisplay::DisplayType aDisplayType, + android::IGraphicBufferProducer* aProducer = nullptr); + + nsresult RemoveScreen(GonkDisplay::DisplayType aDisplayType); protected: ~nsScreenManagerGonk(); void VsyncControl(bool aEnabled); - uint32_t GetIdFromType(uint32_t aDisplayType); + uint32_t GetIdFromType(GonkDisplay::DisplayType aDisplayType); + bool IsScreenConnected(uint32_t aId); bool mInitialized; nsTArray> mScreens; diff --git a/widget/gonk/nsWindow.cpp b/widget/gonk/nsWindow.cpp index 1867965037c..3c38d5331dd 100644 --- a/widget/gonk/nsWindow.cpp +++ b/widget/gonk/nsWindow.cpp @@ -18,7 +18,6 @@ #include #include "android/log.h" - #include "mozilla/dom/TabParent.h" #include "mozilla/Preferences.h" #include "mozilla/Services.h" @@ -45,8 +44,6 @@ #include "mozilla/layers/APZCTreeManager.h" #include "mozilla/layers/APZThreadUtils.h" #include "mozilla/layers/CompositorParent.h" -#include "mozilla/layers/InputAPZContext.h" -#include "mozilla/MouseEvents.h" #include "mozilla/TouchEvents.h" #include "HwcComposer2D.h" @@ -549,11 +546,9 @@ nsWindow::SetNativeData(uint32_t aDataType, uintptr_t aVal) case NS_NATIVE_OPENGL_CONTEXT: // Called after primary display's GLContextEGL creation. GLContext* context = reinterpret_cast(aVal); - - HwcComposer2D* hwc = HwcComposer2D::GetInstance(); - hwc->SetEGLInfo(GLContextEGL::Cast(context)->GetEGLDisplay(), - GLContextEGL::Cast(context)->GetEGLSurface(), - context); + mScreen->SetEGLInfo(GLContextEGL::Cast(context)->GetEGLDisplay(), + GLContextEGL::Cast(context)->GetEGLSurface(), + context); return; } } @@ -810,6 +805,12 @@ nsWindow::GetNaturalBounds() return mScreen->GetNaturalBounds(); } +nsScreenGonk* +nsWindow::GetScreen() +{ + return mScreen; +} + bool nsWindow::NeedsPaint() { @@ -822,7 +823,7 @@ nsWindow::NeedsPaint() Composer2D* nsWindow::GetComposer2D() { - if (!mScreen->IsPrimaryScreen()) { + if (mScreen->GetDisplayType() == GonkDisplay::DISPLAY_VIRTUAL) { return nullptr; } diff --git a/widget/gonk/nsWindow.h b/widget/gonk/nsWindow.h index d148bb0b17e..50b37bfbb81 100644 --- a/widget/gonk/nsWindow.h +++ b/widget/gonk/nsWindow.h @@ -123,6 +123,8 @@ public: void ConfigureAPZControllerThread() override; + nsScreenGonk* GetScreen(); + protected: nsWindow* mParent; bool mVisible; diff --git a/widget/moz.build b/widget/moz.build index a9d97dc5d58..cb7673a0f25 100644 --- a/widget/moz.build +++ b/widget/moz.build @@ -66,6 +66,7 @@ XPIDL_SOURCES += [ 'nsIClipboardHelper.idl', 'nsIClipboardOwner.idl', 'nsIColorPicker.idl', + 'nsIDisplayInfo.idl', 'nsIDragService.idl', 'nsIDragSession.idl', 'nsIFilePicker.idl', diff --git a/widget/nsIDisplayInfo.idl b/widget/nsIDisplayInfo.idl new file mode 100644 index 00000000000..69d5064e4e3 --- /dev/null +++ b/widget/nsIDisplayInfo.idl @@ -0,0 +1,14 @@ +/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * 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 "nsISupports.idl" + +[scriptable, uuid(615bc23d-6346-4b15-9c10-add002f140b6)] +interface nsIDisplayInfo : nsISupports +{ + readonly attribute long id; + readonly attribute boolean connected; +};