mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1138287 - Part 2: Support multi-screen on Gonk platform. r=mwu, r=sotaro, r=jgilbert, r=mattwoodrow
This commit is contained in:
parent
8c9a101347
commit
0c646b32d4
@ -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<nsWindow*>(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<nsIWidget*>(aWindow))) {
|
||||
MOZ_CRASH("Failed to create EGLConfig!\n");
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
|
@ -57,6 +57,8 @@
|
||||
#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17
|
||||
#include "libdisplay/GonkDisplay.h" // for GonkDisplay
|
||||
#include <ui/Fence.h>
|
||||
#include "nsWindow.h"
|
||||
#include "nsScreenManagerGonk.h"
|
||||
#endif
|
||||
|
||||
namespace mozilla {
|
||||
@ -1401,8 +1403,9 @@ CompositorOGL::SetDispAcquireFence(Layer* aLayer)
|
||||
if (!aLayer) {
|
||||
return;
|
||||
}
|
||||
|
||||
RefPtr<FenceHandle::FdObj> fence = new FenceHandle::FdObj(GetGonkDisplay()->GetPrevDispAcquireFd());
|
||||
nsWindow* window = static_cast<nsWindow*>(mWidget);
|
||||
RefPtr<FenceHandle::FdObj> fence = new FenceHandle::FdObj(
|
||||
window->GetScreen()->GetPrevDispAcquireFd());
|
||||
mReleaseFenceHandle.Merge(FenceHandle(fence));
|
||||
}
|
||||
|
||||
|
@ -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<HwcComposer2D> 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<nsScreenManagerGonk> 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<nsWindow*>(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<nsWindow*>(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<nsWindow*>(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;
|
||||
|
@ -31,6 +31,8 @@
|
||||
#include <utils/Timers.h>
|
||||
#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;
|
||||
|
@ -17,8 +17,14 @@
|
||||
#define GONKDISPLAY_H
|
||||
|
||||
#include <system/window.h>
|
||||
#include <utils/StrongPointer.h>
|
||||
#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<ANativeWindow> mNativeWindow;
|
||||
#if ANDROID_VERSION >= 17
|
||||
android::sp<android::DisplaySurface> 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;
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include <cutils/log.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#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<ANativeWindow *>(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<ANativeWindow *>(mFBSurface.get());
|
||||
data.mXdpi = xdpi;
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
__attribute__ ((visibility ("default")))
|
||||
GonkDisplay*
|
||||
GetGonkDisplay()
|
||||
|
@ -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;
|
||||
|
@ -26,11 +26,14 @@
|
||||
#include <hardware/power.h>
|
||||
#include <suspend/autosuspend.h>
|
||||
|
||||
#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>& aNativeWindow,
|
||||
android::sp<android::DisplaySurface>& aDisplaySurface)
|
||||
android::sp<android::DisplaySurface>& aDisplaySurface,
|
||||
uint32_t aWidth, uint32_t aHeight)
|
||||
{
|
||||
#if ANDROID_VERSION >= 21
|
||||
sp<IGraphicBufferProducer> producer;
|
||||
@ -163,7 +159,7 @@ GonkDisplayJB::CreateSurface(android::sp<ANativeWindow>& aNativeWindow,
|
||||
sp<BufferQueue> 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>& 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()
|
||||
|
@ -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>& aNativeWindow,
|
||||
android::sp<android::DisplaySurface>& aDisplaySurface);
|
||||
android::sp<android::DisplaySurface>& aDisplaySurface,
|
||||
uint32_t aWidth, uint32_t aHeight);
|
||||
void PowerOnDisplay(int aDpy);
|
||||
|
||||
hw_module_t const* mModule;
|
||||
hw_module_t const* mFBModule;
|
||||
|
@ -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<nsIObserverService> os = mozilla::services::GetObserverService();
|
||||
if (os) {
|
||||
os->NotifyObservers(mDisplayInfo, "display-changed", nullptr);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
private:
|
||||
nsRefPtr<DisplayInfo> 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;
|
||||
}
|
||||
|
@ -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<ANativeWindow> 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<nsWindow*> mTopWindows;
|
||||
#if ANDROID_VERSION >= 17
|
||||
android::sp<android::DisplaySurface> 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<nsRefPtr<nsScreenGonk>> mScreens;
|
||||
|
@ -18,7 +18,6 @@
|
||||
#include <fcntl.h>
|
||||
|
||||
#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<GLContext*>(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;
|
||||
}
|
||||
|
||||
|
@ -123,6 +123,8 @@ public:
|
||||
|
||||
void ConfigureAPZControllerThread() override;
|
||||
|
||||
nsScreenGonk* GetScreen();
|
||||
|
||||
protected:
|
||||
nsWindow* mParent;
|
||||
bool mVisible;
|
||||
|
@ -66,6 +66,7 @@ XPIDL_SOURCES += [
|
||||
'nsIClipboardHelper.idl',
|
||||
'nsIClipboardOwner.idl',
|
||||
'nsIColorPicker.idl',
|
||||
'nsIDisplayInfo.idl',
|
||||
'nsIDragService.idl',
|
||||
'nsIDragSession.idl',
|
||||
'nsIFilePicker.idl',
|
||||
|
14
widget/nsIDisplayInfo.idl
Normal file
14
widget/nsIDisplayInfo.idl
Normal file
@ -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;
|
||||
};
|
Loading…
Reference in New Issue
Block a user