зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1152135 - Split EGLSurface buffer swap and HWC buffer swap r=mwu,nical,jgilbert
This commit is contained in:
Родитель
b3c27e4396
Коммит
7078be3faa
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
Загрузка…
Ссылка в новой задаче