Bug 1152135 - Split EGLSurface buffer swap and HWC buffer swap r=mwu,nical,jgilbert

This commit is contained in:
Sotaro Ikeda 2015-04-16 18:15:26 -07:00
parent b3c27e4396
commit 7078be3faa
12 changed files with 109 additions and 83 deletions

View File

@ -96,6 +96,14 @@ public:
return mContext;
}
EGLSurface GetEGLSurface() {
return mSurface;
}
EGLDisplay GetEGLDisplay() {
return EGL_DISPLAY();
}
bool BindTex2DOffscreen(GLContext *aOffscreen);
void UnbindTex2DOffscreen(GLContext *aOffscreen);
void BindOffscreenFramebuffer();

View File

@ -230,17 +230,6 @@ GLContextEGL::GLContextEGL(
#ifdef DEBUG
printf_stderr("Initializing context %p surface %p on display %p\n", mContext, mSurface, EGL_DISPLAY());
#endif
#if defined(MOZ_WIDGET_GONK)
if (!mIsOffscreen) {
mHwc = HwcComposer2D::GetInstance();
MOZ_ASSERT(!mHwc->Initialized());
if (mHwc->Init(EGL_DISPLAY(), mSurface, this)) {
NS_WARNING("HWComposer initialization failed!");
mHwc = nullptr;
}
}
#endif
}
GLContextEGL::~GLContextEGL()
@ -466,16 +455,13 @@ GLContextEGL::SwapBuffers()
? mSurfaceOverride
: mSurface;
if (surface) {
#ifdef MOZ_WIDGET_GONK
#if ANDROID_VERSION < 17
if (!mIsOffscreen) {
if (mHwc) {
return mHwc->Render(EGL_DISPLAY(), surface);
} else {
return GetGonkDisplay()->SwapBuffers(EGL_DISPLAY(), surface);
}
} else
// eglSwapBuffers() is called by hwcomposer.
return true;
}
#endif
return sEGLLibrary.fSwapBuffers(EGL_DISPLAY(), surface);
return sEGLLibrary.fSwapBuffers(EGL_DISPLAY(), surface);
} else {
return false;
}

View File

@ -661,16 +661,12 @@ LayerManagerComposite::Render()
/** Our more efficient but less powerful alter ego, if one is available. */
nsRefPtr<Composer2D> composer2D;
composer2D = mCompositor->GetWidget()->GetComposer2D();
// We can't use composert2D if we have layer effects, so only get it
// when we don't have any effects.
if (!haveLayerEffects) {
composer2D = mCompositor->GetWidget()->GetComposer2D();
}
if (!mTarget &&
// We can't use composert2D if we have layer effects
if (!mTarget && !haveLayerEffects &&
gfxPrefs::Composer2DCompositionEnabled() &&
composer2D && composer2D->TryRender(mRoot, mGeometryChanged))
composer2D && composer2D->HasHwc() && composer2D->TryRenderWithHwc(mRoot, mGeometryChanged))
{
LayerScope::SetHWComposed();
if (mFPS) {
@ -684,7 +680,7 @@ LayerManagerComposite::Render()
mInvalidRegion.SetEmpty();
mLastFrameMissedHWC = false;
return;
} else if (!mTarget) {
} else if (!mTarget && !haveLayerEffects) {
mLastFrameMissedHWC = !!composer2D;
}
@ -775,6 +771,10 @@ LayerManagerComposite::Render()
mCompositor->SetFBAcquireFence(mRoot);
}
if (composer2D) {
composer2D->Render();
}
mCompositor->GetWidget()->PostRender(this);
RecordFrame();

View File

@ -52,7 +52,19 @@ public:
* Currently, when TryRender() returns true, the entire framebuffer
* must have been rendered.
*/
virtual bool TryRender(Layer* aRoot, bool aGeometryChanged) = 0;
virtual bool TryRenderWithHwc(Layer* aRoot, bool aGeometryChanged) = 0;
/**
* Return true if Composer2D does composition. Return false if Composer2D
* failed the composition.
*/
virtual bool Render() = 0;
/**
* Return true if Composer2D has a fast composition hardware.
* Return false if Composer2D does not have a fast composition hardware.
*/
virtual bool HasHwc() = 0;
};
} // namespace layers

View File

@ -131,13 +131,19 @@ CompositorOGL::CreateContext()
caps, requireCompatProfile);
}
if (!context)
if (!context) {
context = gl::GLContextProvider::CreateForWindow(mWidget);
}
if (!context) {
NS_WARNING("Failed to create CompositorOGL context");
}
#ifdef MOZ_WIDGET_GONK
mWidget->SetNativeData(NS_NATIVE_OPENGL_CONTEXT,
reinterpret_cast<uintptr_t>(context.get()));
#endif
return context.forget();
}

View File

@ -111,6 +111,8 @@ static StaticRefPtr<HwcComposer2D> sInstance;
HwcComposer2D::HwcComposer2D()
: mHwc(nullptr)
, mList(nullptr)
, mDpy(EGL_NO_DISPLAY)
, mSur(EGL_NO_SURFACE)
, mGLContext(nullptr)
, mMaxLayerCount(0)
, mColorFill(false)
@ -126,21 +128,11 @@ HwcComposer2D::HwcComposer2D()
#if ANDROID_VERSION >= 17
RegisterHwcEventCallback();
#endif
}
HwcComposer2D::~HwcComposer2D() {
free(mList);
}
int
HwcComposer2D::Init(hwc_display_t dpy, hwc_surface_t sur, gl::GLContext* aGLContext)
{
MOZ_ASSERT(!Initialized());
mHwc = (HwcDevice*)GetGonkDisplay()->GetHWCDevice();
if (!mHwc) {
LOGE("Failed to initialize hwc");
return -1;
LOGD("no hwc support");
return;
}
nsIntSize screenSize;
@ -170,12 +162,10 @@ HwcComposer2D::Init(hwc_display_t dpy, hwc_surface_t sur, gl::GLContext* aGLCont
mColorFill = (atoi(propValue) == 1) ? true : false;
mRBSwapSupport = true;
#endif
}
mDpy = dpy;
mSur = sur;
mGLContext = aGLContext;
return 0;
HwcComposer2D::~HwcComposer2D() {
free(mList);
}
HwcComposer2D*
@ -243,7 +233,7 @@ HwcComposer2D::Vsync(int aDisplay, nsecs_t aVsyncTimestamp)
void
HwcComposer2D::Invalidate()
{
if (!Initialized()) {
if (!mHwc) {
LOGE("HwcComposer2D::Invalidate failed!");
return;
}
@ -262,6 +252,14 @@ 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()
{
@ -767,15 +765,13 @@ HwcComposer2D::TryHwComposition()
}
bool
HwcComposer2D::Render(EGLDisplay dpy, EGLSurface sur)
HwcComposer2D::Render()
{
if (!mList) {
// After boot, HWC list hasn't been created yet
return GetGonkDisplay()->SwapBuffers(dpy, sur);
// HWC module does not exist or mList is not created yet.
if (!mHwc || !mList) {
return GetGonkDisplay()->SwapBuffers(mDpy, mSur);
}
GetGonkDisplay()->UpdateFBSurface(dpy, sur);
FramebufferSurface* fbsurface = (FramebufferSurface*)(GetGonkDisplay()->GetFBSurface());
if (!fbsurface) {
LOGE("H/W Composition failed. FBSurface not initialized.");
@ -915,9 +911,9 @@ HwcComposer2D::TryHwComposition()
}
bool
HwcComposer2D::Render(EGLDisplay dpy, EGLSurface sur)
HwcComposer2D::Render()
{
return GetGonkDisplay()->SwapBuffers(dpy, sur);
return GetGonkDisplay()->SwapBuffers(mDpy, mSur);
}
void
@ -928,10 +924,13 @@ HwcComposer2D::Reset()
#endif
bool
HwcComposer2D::TryRender(Layer* aRoot,
bool aGeometryChanged)
HwcComposer2D::TryRenderWithHwc(Layer* aRoot,
bool aGeometryChanged)
{
MOZ_ASSERT(Initialized());
if (!mHwc) {
return false;
}
if (mList) {
setHwcGeometry(aGeometryChanged);
mList->numHwLayers = 0;
@ -960,7 +959,7 @@ HwcComposer2D::TryRender(Layer* aRoot,
SendtoLayerScope();
if (!TryHwComposition()) {
LOGD("H/W Composition failed");
LOGD("Full HWC Composition failed. Fallback to GPU Composition or partial OVERLAY Composition");
LayerScope::CleanLayer();
return false;
}

View File

@ -77,19 +77,17 @@ public:
HwcComposer2D();
virtual ~HwcComposer2D();
int Init(hwc_display_t aDisplay, hwc_surface_t aSurface, gl::GLContext* aGLContext);
bool Initialized() const { return mHwc; }
static HwcComposer2D* GetInstance();
// Returns TRUE if the container has been succesfully rendered
// Returns FALSE if the container cannot be fully rendered
// by this composer so nothing was rendered at all
bool TryRender(layers::Layer* aRoot,
bool aGeometryChanged) override;
virtual bool TryRenderWithHwc(layers::Layer* aRoot,
bool aGeometryChanged) override;
bool Render(EGLDisplay dpy, EGLSurface sur);
virtual bool Render() override;
virtual bool HasHwc() override { return mHwc; }
bool EnableVsync(bool aEnable);
#if ANDROID_VERSION >= 17
@ -99,6 +97,10 @@ public:
#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 fbHandle, int fence);
@ -113,9 +115,9 @@ private:
HwcDevice* mHwc;
HwcList* mList;
hwc_display_t mDpy;
hwc_surface_t mSur;
gl::GLContext* mGLContext;
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;

View File

@ -42,6 +42,9 @@ public:
virtual void* GetFBSurface() = 0;
/**
* Only GonkDisplayICS uses arguments.
*/
virtual bool SwapBuffers(EGLDisplay dpy, EGLSurface sur) = 0;
virtual ANativeWindowBuffer* DequeueBuffer() = 0;

View File

@ -186,8 +186,9 @@ GonkDisplayICS::SwapBuffers(EGLDisplay dpy, EGLSurface sur)
// Only HWC v1.0 needs this call. ICS gonk always needs the call.
mFBSurface->compositionComplete();
if (!mHwc)
return eglSwapBuffers(dpy, sur);
if (!mHwc) {
return true;
}
mHwc->prepare(mHwc, nullptr);
return !mHwc->set(mHwc, dpy, sur, 0);

View File

@ -238,12 +238,6 @@ GonkDisplayJB::SwapBuffers(EGLDisplay dpy, EGLSurface sur)
if (mFBDevice && mFBDevice->compositionComplete) {
mFBDevice->compositionComplete(mFBDevice);
}
#if ANDROID_VERSION == 17
mList->dpy = dpy;
mList->sur = sur;
#endif
eglSwapBuffers(dpy, sur);
return Post(mFBSurface->lastHandle, mFBSurface->GetPrevFBAcquireFd());
}

View File

@ -31,6 +31,7 @@
#include "gfxUtils.h"
#include "GLContextProvider.h"
#include "GLContext.h"
#include "GLContextEGL.h"
#include "nsAutoPtr.h"
#include "nsAppShell.h"
#include "nsIdleService.h"
@ -600,11 +601,28 @@ nsWindow::GetNativeData(uint32_t aDataType)
{
switch (aDataType) {
case NS_NATIVE_WINDOW:
// Called before primary display's EGLSurface creation.
return GetGonkDisplay()->GetNativeWindow();
}
return nullptr;
}
void
nsWindow::SetNativeData(uint32_t aDataType, uintptr_t aVal)
{
switch (aDataType) {
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);
return;
}
}
NS_IMETHODIMP
nsWindow::DispatchEvent(WidgetGUIEvent* aEvent, nsEventStatus& aStatus)
{
@ -857,11 +875,7 @@ nsWindow::NeedsPaint()
Composer2D*
nsWindow::GetComposer2D()
{
if (HwcComposer2D* hwc = HwcComposer2D::GetInstance()) {
return hwc->Initialized() ? hwc : nullptr;
}
return nullptr;
return HwcComposer2D::GetInstance();
}
// nsScreenGonk.cpp

View File

@ -82,6 +82,7 @@ public:
NS_IMETHOD ConfigureChildren(const nsTArray<nsIWidget::Configuration>&);
NS_IMETHOD Invalidate(const nsIntRect &aRect);
virtual void* GetNativeData(uint32_t aDataType);
virtual void SetNativeData(uint32_t aDataType, uintptr_t aVal);
NS_IMETHOD SetTitle(const nsAString& aTitle)
{
return NS_OK;