mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1186000 - Support screen mirroring to HDMI display on gonk r=mwu,mattwoodrow
This commit is contained in:
parent
be1f9cecbe
commit
def035db89
@ -996,6 +996,9 @@ pref("gfx.canvas.max-size-for-skia-gl", -1);
|
||||
// enable fence with readpixels for SurfaceStream
|
||||
pref("gfx.gralloc.fence-with-readpixels", true);
|
||||
|
||||
// enable screen mirroring to external display
|
||||
pref("gfx.screen-mirroring.enabled", true);
|
||||
|
||||
// The url of the page used to display network error details.
|
||||
pref("b2g.neterror.url", "net_error.html");
|
||||
|
||||
|
@ -55,11 +55,17 @@
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
#include <android/log.h>
|
||||
#include "AndroidBridge.h"
|
||||
#endif
|
||||
#if defined(MOZ_WIDGET_ANDROID) || defined(MOZ_WIDGET_GONK)
|
||||
#include "opengl/CompositorOGL.h"
|
||||
#include "GLContextEGL.h"
|
||||
#include "GLContextProvider.h"
|
||||
#include "ScopedGLHelpers.h"
|
||||
#endif
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
#include "nsScreenManagerGonk.h"
|
||||
#include "nsWindow.h"
|
||||
#endif
|
||||
#include "GeckoProfiler.h"
|
||||
#include "TextRenderer.h" // for TextRenderer
|
||||
|
||||
@ -302,7 +308,7 @@ LayerManagerComposite::EndTransaction(const TimeStamp& aTimeStamp,
|
||||
ApplyOcclusionCulling(mRoot, opaque);
|
||||
|
||||
Render();
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
#if defined(MOZ_WIDGET_ANDROID) || defined(MOZ_WIDGET_GONK)
|
||||
RenderToPresentationSurface();
|
||||
#endif
|
||||
mGeometryChanged = false;
|
||||
@ -780,7 +786,7 @@ LayerManagerComposite::Render()
|
||||
RecordFrame();
|
||||
}
|
||||
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
#if defined(MOZ_WIDGET_ANDROID) || defined(MOZ_WIDGET_GONK)
|
||||
class ScopedCompositorProjMatrix {
|
||||
public:
|
||||
ScopedCompositorProjMatrix(CompositorOGL* aCompositor, const Matrix4x4& aProjMatrix):
|
||||
@ -854,6 +860,7 @@ private:
|
||||
void
|
||||
LayerManagerComposite::RenderToPresentationSurface()
|
||||
{
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
if (!AndroidBridge::Bridge()) {
|
||||
return;
|
||||
}
|
||||
@ -886,17 +893,60 @@ LayerManagerComposite::RenderToPresentationSurface()
|
||||
|
||||
const IntSize windowSize = AndroidBridge::Bridge()->GetNativeWindowSize(window);
|
||||
|
||||
#elif defined(MOZ_WIDGET_GONK)
|
||||
CompositorOGL* compositor = static_cast<CompositorOGL*>(mCompositor.get());
|
||||
nsScreenGonk* screen = static_cast<nsWindow*>(mCompositor->GetWidget())->GetScreen();
|
||||
if (!screen->IsPrimaryScreen()) {
|
||||
// Only primary screen support mirroring
|
||||
return;
|
||||
}
|
||||
|
||||
nsWindow* mirrorScreenWidget = screen->GetMirroringWidget();
|
||||
if (!mirrorScreenWidget) {
|
||||
// No mirroring
|
||||
return;
|
||||
}
|
||||
|
||||
nsScreenGonk* mirrorScreen = mirrorScreenWidget->GetScreen();
|
||||
if (!mirrorScreen->GetTopWindows().IsEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
EGLSurface surface = mirrorScreen->GetEGLSurface();
|
||||
if (surface == LOCAL_EGL_NO_SURFACE) {
|
||||
// Create GLContext
|
||||
nsRefPtr<GLContext> gl = gl::GLContextProvider::CreateForWindow(mirrorScreenWidget);
|
||||
mirrorScreenWidget->SetNativeData(NS_NATIVE_OPENGL_CONTEXT,
|
||||
reinterpret_cast<uintptr_t>(gl.get()));
|
||||
surface = mirrorScreen->GetEGLSurface();
|
||||
if (surface == LOCAL_EGL_NO_SURFACE) {
|
||||
// Failed to create EGLSurface
|
||||
return;
|
||||
}
|
||||
}
|
||||
GLContext* gl = compositor->gl();
|
||||
GLContextEGL* egl = GLContextEGL::Cast(gl);
|
||||
const IntSize windowSize = mirrorScreen->GetNaturalBounds().Size();
|
||||
#endif
|
||||
|
||||
if ((windowSize.width <= 0) || (windowSize.height <= 0)) {
|
||||
return;
|
||||
}
|
||||
|
||||
ScreenRotation rotation = compositor->GetScreenRotation();
|
||||
|
||||
const int actualWidth = windowSize.width;
|
||||
const int actualHeight = windowSize.height;
|
||||
|
||||
const gfx::IntSize originalSize = compositor->GetDestinationSurfaceSize();
|
||||
const nsIntRect originalRect = nsIntRect(0, 0, originalSize.width, originalSize.height);
|
||||
|
||||
const int pageWidth = originalSize.width;
|
||||
const int pageHeight = originalSize.height;
|
||||
int pageWidth = originalSize.width;
|
||||
int pageHeight = originalSize.height;
|
||||
if (rotation == ROTATION_90 || rotation == ROTATION_270) {
|
||||
pageWidth = originalSize.height;
|
||||
pageHeight = originalSize.width;
|
||||
}
|
||||
|
||||
float scale = 1.0;
|
||||
|
||||
@ -910,42 +960,47 @@ LayerManagerComposite::RenderToPresentationSurface()
|
||||
ScopedCompostitorSurfaceSize overrideSurfaceSize(compositor, actualSize);
|
||||
|
||||
const ScreenPoint offset((actualWidth - (int)(scale * pageWidth)) / 2, 0);
|
||||
ScopedCompositorRenderOffset overrideRenderOffset(compositor, offset);
|
||||
ScopedContextSurfaceOverride overrideSurface(egl, surface);
|
||||
|
||||
Matrix viewMatrix = ComputeTransformForRotation(originalRect,
|
||||
rotation);
|
||||
viewMatrix.Invert(); // unrotate
|
||||
viewMatrix.PostScale(scale, scale);
|
||||
viewMatrix.PostTranslate(offset.x, offset.y);
|
||||
Matrix4x4 matrix = Matrix4x4::From2D(viewMatrix);
|
||||
|
||||
mRoot->ComputeEffectiveTransforms(matrix);
|
||||
nsIntRegion opaque;
|
||||
ApplyOcclusionCulling(mRoot, opaque);
|
||||
|
||||
nsIntRegion invalid;
|
||||
Rect bounds(0.0f, 0.0f, scale * pageWidth, (float)actualHeight);
|
||||
Rect rect, actualBounds;
|
||||
|
||||
mCompositor->BeginFrame(invalid, nullptr, bounds, &rect, &actualBounds);
|
||||
|
||||
// Override the projection matrix since the presentation frame buffer
|
||||
// is probably not the same size as the device frame buffer. The override
|
||||
// projection matrix also scales the content to fit into the presentation
|
||||
// frame buffer.
|
||||
Matrix viewMatrix;
|
||||
viewMatrix.PreTranslate(-1.0, 1.0);
|
||||
viewMatrix.PreScale((2.0f * scale) / (float)actualWidth, (2.0f * scale) / (float)actualHeight);
|
||||
viewMatrix.PreScale(1.0f, -1.0f);
|
||||
viewMatrix.PreTranslate((int)((float)offset.x / scale), offset.y);
|
||||
|
||||
Matrix4x4 projMatrix = Matrix4x4::From2D(viewMatrix);
|
||||
|
||||
ScopedCompositorProjMatrix overrideProjMatrix(compositor, projMatrix);
|
||||
|
||||
// The Java side of Fennec sets a scissor rect that accounts for
|
||||
// chrome such as the URL bar. Override that so that the entire frame buffer
|
||||
// is cleared.
|
||||
ScopedScissorRect screen(egl, 0, 0, actualWidth, actualHeight);
|
||||
ScopedScissorRect scissorRect(egl, 0, 0, actualWidth, actualHeight);
|
||||
egl->fClearColor(0.0, 0.0, 0.0, 0.0);
|
||||
egl->fClear(LOCAL_GL_COLOR_BUFFER_BIT);
|
||||
|
||||
const IntRect clipRect = IntRect(0, 0, (int)(scale * pageWidth), actualHeight);
|
||||
const IntRect clipRect = IntRect(0, 0, actualWidth, actualHeight);
|
||||
|
||||
RootLayer()->Prepare(RenderTargetPixel::FromUntyped(clipRect));
|
||||
RootLayer()->RenderLayer(clipRect);
|
||||
|
||||
mCompositor->EndFrame();
|
||||
mCompositor->SetDispAcquireFence(mRoot);
|
||||
mCompositor->SetDispAcquireFence(mRoot); // Call after EndFrame()
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
nsRefPtr<Composer2D> composer2D;
|
||||
composer2D = mCompositor->GetWidget()->GetComposer2D();
|
||||
if (composer2D) {
|
||||
composer2D->Render(mirrorScreenWidget);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -301,7 +301,7 @@ private:
|
||||
* Render the current layer tree to the active target.
|
||||
*/
|
||||
void Render();
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
#if defined(MOZ_WIDGET_ANDROID) || defined(MOZ_WIDGET_GONK)
|
||||
void RenderToPresentationSurface();
|
||||
#endif
|
||||
|
||||
|
@ -263,6 +263,7 @@ private:
|
||||
DECL_GFX_PREF(Once, "gfx.vsync.hw-vsync.enabled", HardwareVsyncEnabled, bool, false);
|
||||
DECL_GFX_PREF(Once, "gfx.vsync.refreshdriver", VsyncAlignedRefreshDriver, bool, false);
|
||||
DECL_GFX_PREF(Once, "gfx.work-around-driver-bugs", WorkAroundDriverBugs, bool, true);
|
||||
DECL_GFX_PREF(Once, "gfx.screen-mirroring.enabled", ScreenMirroringEnabled, bool, false);
|
||||
|
||||
DECL_GFX_PREF(Live, "gl.msaa-level", MSAALevel, uint32_t, 2);
|
||||
DECL_GFX_PREF(Live, "gl.require-hardware", RequireHardwareGL, bool, false);
|
||||
|
@ -751,6 +751,9 @@ HwcComposer2D::Render(nsIWidget* aWidget)
|
||||
mList->hwLayers[mList->numHwLayers - 1].handle = dispSurface->lastHandle;
|
||||
mList->hwLayers[mList->numHwLayers - 1].acquireFenceFd = dispSurface->GetPrevDispAcquireFd();
|
||||
} else {
|
||||
// Update screen rect to handle a case that TryRenderWithHwc() is not called.
|
||||
mScreenRect = screen->GetNaturalBounds();
|
||||
|
||||
mList->flags = HWC_GEOMETRY_CHANGED;
|
||||
mList->numHwLayers = 2;
|
||||
mList->hwLayers[0].hints = 0;
|
||||
@ -773,7 +776,8 @@ HwcComposer2D::Prepare(buffer_handle_t dispHandle, int fence, nsScreenGonk* scre
|
||||
if (mPrepared) {
|
||||
LOGE("Multiple hwc prepare calls!");
|
||||
}
|
||||
mHal->Prepare(mList, screen->GetDisplayType(), dispHandle, fence);
|
||||
hwc_rect_t dispRect = {0, 0, mScreenRect.width, mScreenRect.height};
|
||||
mHal->Prepare(mList, screen->GetDisplayType(), dispRect, dispHandle, fence);
|
||||
mPrepared = true;
|
||||
}
|
||||
|
||||
|
@ -32,8 +32,6 @@ HwcHAL::HwcHAL()
|
||||
printf_stderr("HwcHAL Error: Cannot load hwcomposer");
|
||||
return;
|
||||
}
|
||||
|
||||
GetHwcAttributes();
|
||||
}
|
||||
|
||||
HwcHAL::~HwcHAL()
|
||||
@ -79,6 +77,7 @@ HwcHAL::ResetHwc()
|
||||
int
|
||||
HwcHAL::Prepare(HwcList *aList,
|
||||
uint32_t aDisp,
|
||||
hwc_rect_t aDispRect,
|
||||
buffer_handle_t aHandle,
|
||||
int aFenceFd)
|
||||
{
|
||||
@ -103,8 +102,8 @@ HwcHAL::Prepare(HwcList *aList,
|
||||
aList->hwLayers[idx].handle = aHandle;
|
||||
aList->hwLayers[idx].blending = HWC_BLENDING_PREMULT;
|
||||
aList->hwLayers[idx].compositionType = HWC_FRAMEBUFFER_TARGET;
|
||||
SetCrop(aList->hwLayers[idx], mHwcRect);
|
||||
aList->hwLayers[idx].displayFrame = mHwcRect;
|
||||
SetCrop(aList->hwLayers[idx], aDispRect);
|
||||
aList->hwLayers[idx].displayFrame = aDispRect;
|
||||
aList->hwLayers[idx].visibleRegionScreen.numRects = 1;
|
||||
aList->hwLayers[idx].visibleRegionScreen.rects = &aList->hwLayers[idx].displayFrame;
|
||||
aList->hwLayers[idx].acquireFenceFd = aFenceFd;
|
||||
@ -195,20 +194,6 @@ HwcHAL::RegisterHwcEventCallback(const HwcHALProcs_t &aProcs)
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
HwcHAL::GetHwcAttributes()
|
||||
{
|
||||
int32_t values[2];
|
||||
const uint32_t attrs[] = {
|
||||
HWC_DISPLAY_WIDTH,
|
||||
HWC_DISPLAY_HEIGHT,
|
||||
HWC_DISPLAY_NO_ATTRIBUTE
|
||||
};
|
||||
|
||||
mHwc->getDisplayAttributes(mHwc, 0, 0, attrs, values);
|
||||
mHwcRect = {0, 0, values[0], values[1]};
|
||||
}
|
||||
|
||||
uint32_t
|
||||
HwcHAL::GetAPIVersion() const
|
||||
{
|
||||
|
@ -31,8 +31,6 @@ public:
|
||||
|
||||
virtual bool HasHwc() const override { return static_cast<bool>(mHwc); }
|
||||
|
||||
virtual const hwc_rect_t GetHwcRect() const override { return mHwcRect; }
|
||||
|
||||
virtual void SetEGLInfo(hwc_display_t aDpy,
|
||||
hwc_surface_t aSur) override { }
|
||||
|
||||
@ -45,6 +43,7 @@ public:
|
||||
|
||||
virtual int Prepare(HwcList *aList,
|
||||
uint32_t aDisp,
|
||||
hwc_rect_t aDispRect,
|
||||
buffer_handle_t aHandle,
|
||||
int aFenceFd) override;
|
||||
|
||||
@ -60,13 +59,10 @@ public:
|
||||
virtual bool RegisterHwcEventCallback(const HwcHALProcs_t &aProcs) override;
|
||||
|
||||
private:
|
||||
void GetHwcAttributes();
|
||||
|
||||
uint32_t GetAPIVersion() const;
|
||||
|
||||
private:
|
||||
HwcDevice *mHwc = nullptr;
|
||||
hwc_rect_t mHwcRect = {0};
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
@ -85,9 +85,6 @@ public:
|
||||
// Check if mHwc exists
|
||||
virtual bool HasHwc() const = 0;
|
||||
|
||||
// Get HwcRect
|
||||
virtual const hwc_rect_t GetHwcRect() const = 0;
|
||||
|
||||
// Set EGL info (only ICS need this info)
|
||||
virtual void SetEGLInfo(hwc_display_t aEGLDisplay,
|
||||
hwc_surface_t aEGLSurface) = 0;
|
||||
@ -105,6 +102,7 @@ public:
|
||||
// HwcDevice prepare
|
||||
virtual int Prepare(HwcList *aList,
|
||||
uint32_t aDisp,
|
||||
hwc_rect_t aDispRect,
|
||||
buffer_handle_t aHandle,
|
||||
int aFenceFd) = 0;
|
||||
|
||||
|
@ -86,6 +86,7 @@ HwcICS::ResetHwc()
|
||||
int
|
||||
HwcICS::Prepare(HwcList *aList,
|
||||
uint32_t aDisp,
|
||||
hwc_rect_t aDispRect,
|
||||
buffer_handle_t aHandle,
|
||||
int aFenceFd)
|
||||
{
|
||||
|
@ -31,8 +31,6 @@ public:
|
||||
|
||||
virtual bool HasHwc() const override { return static_cast<bool>(mHwc); }
|
||||
|
||||
virtual const hwc_rect_t GetHwcRect() const override { return {0}; }
|
||||
|
||||
virtual void SetEGLInfo(hwc_display_t aEGLDisplay,
|
||||
hwc_surface_t aEGLSurface) override;
|
||||
|
||||
@ -45,6 +43,7 @@ public:
|
||||
|
||||
virtual int Prepare(HwcList *aList,
|
||||
uint32_t aDisp,
|
||||
hwc_rect_t aDispRect,
|
||||
buffer_handle_t aHandle,
|
||||
int aFenceFd) override;
|
||||
|
||||
|
@ -121,6 +121,7 @@ nsScreenGonk::nsScreenGonk(uint32_t aId,
|
||||
#if ANDROID_VERSION >= 17
|
||||
, mDisplaySurface(aNativeData.mDisplaySurface)
|
||||
#endif
|
||||
, mIsMirroring(false)
|
||||
, mDisplayType(aDisplayType)
|
||||
, mEGLDisplay(EGL_NO_DISPLAY)
|
||||
, mEGLSurface(EGL_NO_SURFACE)
|
||||
@ -143,8 +144,22 @@ nsScreenGonk::nsScreenGonk(uint32_t aId,
|
||||
mColorDepth = SurfaceFormatToColorDepth(mSurfaceFormat);
|
||||
}
|
||||
|
||||
static void
|
||||
ReleaseGLContextSync(mozilla::gl::GLContext* aGLContext) {
|
||||
MOZ_ASSERT(CompositorParent::IsInCompositorThread());
|
||||
aGLContext->Release();
|
||||
}
|
||||
|
||||
nsScreenGonk::~nsScreenGonk()
|
||||
{
|
||||
// Release GLContext on compositor thread
|
||||
if (mGLContext) {
|
||||
CompositorParent::CompositorLoop()->PostTask(
|
||||
FROM_HERE,
|
||||
NewRunnableFunction(&ReleaseGLContextSync,
|
||||
mGLContext.forget().take()));
|
||||
mGLContext = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
@ -359,7 +374,8 @@ nsScreenGonk::GetDisplayType()
|
||||
}
|
||||
|
||||
void
|
||||
nsScreenGonk::SetEGLInfo(hwc_display_t aDisplay, hwc_surface_t aSurface,
|
||||
nsScreenGonk::SetEGLInfo(hwc_display_t aDisplay,
|
||||
hwc_surface_t aSurface,
|
||||
gl::GLContext* aGLContext)
|
||||
{
|
||||
MOZ_ASSERT(CompositorParent::IsInCompositorThread());
|
||||
@ -378,10 +394,116 @@ nsScreenGonk::GetEGLDisplay()
|
||||
hwc_surface_t
|
||||
nsScreenGonk::GetEGLSurface()
|
||||
{
|
||||
MOZ_ASSERT(CompositorParent::IsInCompositorThread());
|
||||
return mEGLSurface;
|
||||
}
|
||||
|
||||
static void
|
||||
UpdateMirroringWidgetSync(nsScreenGonk* aScreen, nsWindow* aWindow) {
|
||||
MOZ_ASSERT(CompositorParent::IsInCompositorThread());
|
||||
already_AddRefed<nsWindow> window(aWindow);
|
||||
aScreen->UpdateMirroringWidget(window);
|
||||
}
|
||||
|
||||
bool
|
||||
nsScreenGonk::EnableMirroring()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(!IsPrimaryScreen());
|
||||
|
||||
nsRefPtr<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;
|
||||
nsRefPtr<nsWindow> window = new nsWindow();
|
||||
window->Create(nullptr, nullptr, mNaturalBounds, &initData);
|
||||
MOZ_ASSERT(static_cast<nsWindow*>(window)->GetScreen() == this);
|
||||
|
||||
// Update mMirroringWidget on compositor thread
|
||||
CompositorParent::CompositorLoop()->PostTask(
|
||||
FROM_HERE,
|
||||
NewRunnableFunction(&UpdateMirroringWidgetSync,
|
||||
primaryScreen,
|
||||
window.forget().take()));
|
||||
|
||||
mIsMirroring = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
nsScreenGonk::DisableMirroring()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(!IsPrimaryScreen());
|
||||
|
||||
mIsMirroring = false;
|
||||
nsRefPtr<nsScreenGonk> primaryScreen = nsScreenManagerGonk::GetPrimaryScreen();
|
||||
NS_ENSURE_TRUE(primaryScreen, false);
|
||||
|
||||
bool ret = primaryScreen->ClearMirroringScreen(this);
|
||||
NS_ENSURE_TRUE(ret, false);
|
||||
|
||||
// Update mMirroringWidget on compositor thread
|
||||
CompositorParent::CompositorLoop()->PostTask(
|
||||
FROM_HERE,
|
||||
NewRunnableFunction(&UpdateMirroringWidgetSync,
|
||||
primaryScreen,
|
||||
nullptr));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
nsScreenGonk::SetMirroringScreen(nsScreenGonk* aScreen)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(IsPrimaryScreen());
|
||||
|
||||
if (mMirroringScreen) {
|
||||
return false;
|
||||
}
|
||||
mMirroringScreen = mMirroringScreen;
|
||||
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(CompositorParent::IsInCompositorThread());
|
||||
MOZ_ASSERT(IsPrimaryScreen());
|
||||
|
||||
if (mMirroringWidget) {
|
||||
nsCOMPtr<nsIWidget> widget = mMirroringWidget.forget();
|
||||
NS_ReleaseOnMainThread(widget);
|
||||
}
|
||||
mMirroringWidget = aWindow;
|
||||
}
|
||||
|
||||
nsWindow*
|
||||
nsScreenGonk::GetMirroringWidget()
|
||||
{
|
||||
MOZ_ASSERT(CompositorParent::IsInCompositorThread());
|
||||
MOZ_ASSERT(IsPrimaryScreen());
|
||||
|
||||
return mMirroringWidget;
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsScreenManagerGonk, nsIScreenManager)
|
||||
|
||||
nsScreenManagerGonk::nsScreenManagerGonk()
|
||||
@ -611,7 +733,7 @@ NotifyDisplayChange(uint32_t aId, bool aConnected)
|
||||
|
||||
nsresult
|
||||
nsScreenManagerGonk::AddScreen(GonkDisplay::DisplayType aDisplayType,
|
||||
android::IGraphicBufferProducer* aProducer)
|
||||
android::IGraphicBufferProducer* aSink)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
@ -622,13 +744,19 @@ nsScreenManagerGonk::AddScreen(GonkDisplay::DisplayType aDisplayType,
|
||||
NS_ENSURE_TRUE(!IsScreenConnected(id), NS_ERROR_FAILURE);
|
||||
|
||||
GonkDisplay::NativeData nativeData =
|
||||
GetGonkDisplay()->GetNativeData(aDisplayType, aProducer);
|
||||
GetGonkDisplay()->GetNativeData(aDisplayType, aSink);
|
||||
nsScreenGonk* screen = new nsScreenGonk(id, aDisplayType, nativeData);
|
||||
|
||||
mScreens.AppendElement(screen);
|
||||
|
||||
NotifyDisplayChange(id, true);
|
||||
|
||||
// By default, non primary screen does mirroring.
|
||||
if (aDisplayType != GonkDisplay::DISPLAY_PRIMARY &&
|
||||
gfxPrefs::ScreenMirroringEnabled()) {
|
||||
screen->EnableMirroring();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -645,6 +773,9 @@ nsScreenManagerGonk::RemoveScreen(GonkDisplay::DisplayType aDisplayType)
|
||||
|
||||
for (size_t i = 0; i < mScreens.Length(); i++) {
|
||||
if (mScreens[i]->GetId() == screenId) {
|
||||
if (mScreens[i]->IsMirroring()) {
|
||||
mScreens[i]->DisableMirroring();
|
||||
}
|
||||
mScreens.RemoveElementAt(i);
|
||||
break;
|
||||
}
|
||||
|
@ -17,14 +17,16 @@
|
||||
#ifndef nsScreenManagerGonk_h___
|
||||
#define nsScreenManagerGonk_h___
|
||||
|
||||
#include "mozilla/Hal.h"
|
||||
|
||||
#include "cutils/properties.h"
|
||||
#include "hardware/hwcomposer.h"
|
||||
|
||||
#include "libdisplay/GonkDisplay.h"
|
||||
#include "mozilla/Hal.h"
|
||||
#include "mozilla/Mutex.h"
|
||||
#include "nsBaseScreen.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIScreenManager.h"
|
||||
#include "nsProxyRelease.h"
|
||||
|
||||
#include <android/native_window.h>
|
||||
|
||||
@ -87,11 +89,25 @@ public:
|
||||
return mTopWindows;
|
||||
}
|
||||
|
||||
// Set EGL info of primary display. Used for BLIT Composition.
|
||||
// Non-primary screen only
|
||||
bool EnableMirroring();
|
||||
bool DisableMirroring();
|
||||
bool IsMirroring()
|
||||
{
|
||||
return mIsMirroring;
|
||||
}
|
||||
|
||||
// Primary screen only
|
||||
bool SetMirroringScreen(nsScreenGonk* aScreen);
|
||||
bool ClearMirroringScreen(nsScreenGonk* aScreen);
|
||||
|
||||
// Called only on compositor thread
|
||||
void SetEGLInfo(hwc_display_t aDisplay, hwc_surface_t aSurface,
|
||||
mozilla::gl::GLContext* aGLContext);
|
||||
hwc_display_t GetEGLDisplay();
|
||||
hwc_surface_t GetEGLSurface();
|
||||
void UpdateMirroringWidget(already_AddRefed<nsWindow>& aWindow); // Primary screen only
|
||||
nsWindow* GetMirroringWidget(); // Primary screen only
|
||||
|
||||
protected:
|
||||
uint32_t mId;
|
||||
@ -107,12 +123,15 @@ protected:
|
||||
#if ANDROID_VERSION >= 17
|
||||
android::sp<android::DisplaySurface> mDisplaySurface;
|
||||
#endif
|
||||
bool mIsMirroring; // Non-primary screen only
|
||||
nsRefPtr<nsScreenGonk> mMirroringScreen; // Primary screen only
|
||||
|
||||
// Accessed and updated only on compositor thread
|
||||
GonkDisplay::DisplayType mDisplayType;
|
||||
hwc_display_t mEGLDisplay;
|
||||
hwc_surface_t mEGLSurface;
|
||||
mozilla::gl::GLContext* mGLContext;
|
||||
nsRefPtr<mozilla::gl::GLContext> mGLContext;
|
||||
nsRefPtr<nsWindow> mMirroringWidget; // Primary screen only
|
||||
};
|
||||
|
||||
class nsScreenManagerGonk final : public nsIScreenManager
|
||||
@ -133,7 +152,7 @@ public:
|
||||
void DisplayEnabled(bool aEnabled);
|
||||
|
||||
nsresult AddScreen(GonkDisplay::DisplayType aDisplayType,
|
||||
android::IGraphicBufferProducer* aProducer = nullptr);
|
||||
android::IGraphicBufferProducer* aSink = nullptr);
|
||||
|
||||
nsresult RemoveScreen(GonkDisplay::DisplayType aDisplayType);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user