mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 919676 - Fix multiple hwc prepare calls with different layer lists. r=mwu, r=dwilson
This commit is contained in:
parent
d9ea1eb4df
commit
901afbe792
@ -605,9 +605,13 @@ public:
|
||||
{
|
||||
if (mSurface && !mPlatformContext) {
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
if (!mIsOffscreen)
|
||||
return GetGonkDisplay()->SwapBuffers(EGL_DISPLAY(), mSurface);
|
||||
else
|
||||
if (!mIsOffscreen) {
|
||||
if (mHwc) {
|
||||
return mHwc->Render(EGL_DISPLAY(), mSurface);
|
||||
} else {
|
||||
return GetGonkDisplay()->SwapBuffers(EGL_DISPLAY(), mSurface);
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
return sEGLLibrary.fSwapBuffers(EGL_DISPLAY(), mSurface);
|
||||
} else {
|
||||
|
@ -445,45 +445,114 @@ HwcComposer2D::TryHwComposition()
|
||||
{
|
||||
FramebufferSurface* fbsurface = (FramebufferSurface*)(GetGonkDisplay()->GetFBSurface());
|
||||
|
||||
if (!(fbsurface && fbsurface->lastHandle)) {
|
||||
LOGD("H/W Composition failed. FBSurface not initialized.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Add FB layer
|
||||
int idx = mList->numHwLayers++;
|
||||
if (idx >= mMaxLayerCount) {
|
||||
if (!ReallocLayerList() || idx >= mMaxLayerCount) {
|
||||
LOGE("TryHwComposition failed! Could not add FB layer");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Prepare(fbsurface->lastHandle, -1);
|
||||
|
||||
for (int j = 0; j < idx; j++) {
|
||||
if (mList->hwLayers[j].compositionType == HWC_FRAMEBUFFER) {
|
||||
LOGD("GPU or Partial HWC Composition");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Full HWC Composition
|
||||
Commit();
|
||||
|
||||
// No composition on FB layer, so closing releaseFenceFd
|
||||
close(mList->hwLayers[idx].releaseFenceFd);
|
||||
mList->hwLayers[idx].releaseFenceFd = -1;
|
||||
mList->numHwLayers = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
HwcComposer2D::Render(EGLDisplay dpy, EGLSurface sur)
|
||||
{
|
||||
if (!mList) {
|
||||
// After boot, HWC list hasn't been created yet
|
||||
return GetGonkDisplay()->SwapBuffers(dpy, sur);
|
||||
}
|
||||
|
||||
GetGonkDisplay()->UpdateFBSurface(dpy, sur);
|
||||
|
||||
FramebufferSurface* fbsurface = (FramebufferSurface*)(GetGonkDisplay()->GetFBSurface());
|
||||
if (!fbsurface) {
|
||||
LOGE("H/W Composition failed. FBSurface not initialized.");
|
||||
return false;
|
||||
}
|
||||
|
||||
hwc_display_contents_1_t *displays[HWC_NUM_DISPLAY_TYPES] = {NULL};
|
||||
if (mList->numHwLayers != 0) {
|
||||
// No mHwc prepare, if already prepared in current draw cycle
|
||||
mList->hwLayers[mList->numHwLayers - 1].handle = fbsurface->lastHandle;
|
||||
mList->hwLayers[mList->numHwLayers - 1].acquireFenceFd = fbsurface->lastFenceFD;
|
||||
} else {
|
||||
mList->numHwLayers = 2;
|
||||
mList->hwLayers[0].hints = 0;
|
||||
mList->hwLayers[0].compositionType = HWC_BACKGROUND;
|
||||
mList->hwLayers[0].flags = HWC_SKIP_LAYER;
|
||||
mList->hwLayers[0].backgroundColor = {0};
|
||||
mList->hwLayers[0].displayFrame = {0, 0, mScreenRect.width, mScreenRect.height};
|
||||
Prepare(fbsurface->lastHandle, fbsurface->lastFenceFD);
|
||||
}
|
||||
|
||||
// GPU or partial HWC Composition
|
||||
Commit();
|
||||
|
||||
GetGonkDisplay()->SetFBReleaseFd(mList->hwLayers[mList->numHwLayers - 1].releaseFenceFd);
|
||||
mList->numHwLayers = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
HwcComposer2D::Prepare(buffer_handle_t fbHandle, int fence)
|
||||
{
|
||||
int idx = mList->numHwLayers - 1;
|
||||
const hwc_rect_t r = {0, 0, mScreenRect.width, mScreenRect.height};
|
||||
int idx = mList->numHwLayers;
|
||||
hwc_display_contents_1_t *displays[HWC_NUM_DISPLAY_TYPES] = { nullptr };
|
||||
|
||||
displays[HWC_DISPLAY_PRIMARY] = mList;
|
||||
mList->flags = HWC_GEOMETRY_CHANGED;
|
||||
mList->outbufAcquireFenceFd = -1;
|
||||
mList->outbuf = nullptr;
|
||||
mList->retireFenceFd = -1;
|
||||
|
||||
mList->hwLayers[idx].hints = 0;
|
||||
mList->hwLayers[idx].flags = 0;
|
||||
mList->hwLayers[idx].transform = 0;
|
||||
mList->hwLayers[idx].handle = fbsurface->lastHandle;
|
||||
mList->hwLayers[idx].handle = fbHandle;
|
||||
mList->hwLayers[idx].blending = HWC_BLENDING_PREMULT;
|
||||
mList->hwLayers[idx].compositionType = HWC_FRAMEBUFFER_TARGET;
|
||||
mList->hwLayers[idx].sourceCrop = r;
|
||||
mList->hwLayers[idx].displayFrame = r;
|
||||
mList->hwLayers[idx].visibleRegionScreen.numRects = 1;
|
||||
mList->hwLayers[idx].visibleRegionScreen.rects = &mList->hwLayers[idx].sourceCrop;
|
||||
mList->hwLayers[idx].acquireFenceFd = -1;
|
||||
mList->hwLayers[idx].acquireFenceFd = fence;
|
||||
mList->hwLayers[idx].releaseFenceFd = -1;
|
||||
mList->hwLayers[idx].planeAlpha = 0xFF;
|
||||
mList->numHwLayers++;
|
||||
|
||||
mHwc->prepare(mHwc, HWC_NUM_DISPLAY_TYPES, displays);
|
||||
}
|
||||
|
||||
for (int j = 0; j < idx; j++) {
|
||||
if (mList->hwLayers[j].compositionType == HWC_FRAMEBUFFER) {
|
||||
LOGD("GPU or Partial MDP Composition");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
bool
|
||||
HwcComposer2D::Commit()
|
||||
{
|
||||
hwc_display_contents_1_t *displays[HWC_NUM_DISPLAY_TYPES] = { nullptr };
|
||||
displays[HWC_DISPLAY_PRIMARY] = mList;
|
||||
|
||||
// Full MDP Composition
|
||||
mHwc->set(mHwc, HWC_NUM_DISPLAY_TYPES, displays);
|
||||
int err = mHwc->set(mHwc, HWC_NUM_DISPLAY_TYPES, displays);
|
||||
|
||||
for (int i = 0; i <= MAX_HWC_LAYERS; i++) {
|
||||
if (mPrevRelFd[i] <= 0) {
|
||||
@ -504,18 +573,15 @@ HwcComposer2D::TryHwComposition()
|
||||
}
|
||||
|
||||
mPrevRelFd[0] = mList->retireFenceFd;
|
||||
for (uint32_t j = 0; j < idx; j++) {
|
||||
for (uint32_t j = 0; j < (mList->numHwLayers - 1); j++) {
|
||||
if (mList->hwLayers[j].compositionType == HWC_OVERLAY) {
|
||||
mPrevRelFd[j + 1] = mList->hwLayers[j].releaseFenceFd;
|
||||
mList->hwLayers[j].releaseFenceFd = -1;
|
||||
}
|
||||
}
|
||||
|
||||
close(mList->hwLayers[idx].releaseFenceFd);
|
||||
mList->hwLayers[idx].releaseFenceFd = -1;
|
||||
mList->retireFenceFd = -1;
|
||||
mList->numHwLayers = 0;
|
||||
return true;
|
||||
return !err;
|
||||
}
|
||||
#else
|
||||
bool
|
||||
@ -523,6 +589,12 @@ HwcComposer2D::TryHwComposition()
|
||||
{
|
||||
return !mHwc->set(mHwc, mDpy, mSur, mList);
|
||||
}
|
||||
|
||||
bool
|
||||
HwcComposer2D::Render(EGLDisplay dpy, EGLSurface sur)
|
||||
{
|
||||
return GetGonkDisplay()->SwapBuffers(dpy, sur);
|
||||
}
|
||||
#endif
|
||||
|
||||
bool
|
||||
@ -549,13 +621,15 @@ HwcComposer2D::TryRender(Layer* aRoot,
|
||||
aGLWorldTransform))
|
||||
{
|
||||
LOGD("Render aborted. Nothing was drawn to the screen");
|
||||
if (mList) {
|
||||
mList->numHwLayers = 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!TryHwComposition()) {
|
||||
// Full MDP Composition
|
||||
LOGE("H/W Composition failed");
|
||||
return false;
|
||||
LOGD("H/W Composition failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
LOGD("Frame rendered");
|
||||
|
@ -62,7 +62,11 @@ public:
|
||||
// by this composer so nothing was rendered at all
|
||||
bool TryRender(layers::Layer* aRoot, const gfxMatrix& aGLWorldTransform) MOZ_OVERRIDE;
|
||||
|
||||
bool Render(EGLDisplay dpy, EGLSurface sur);
|
||||
|
||||
private:
|
||||
void Prepare(buffer_handle_t fbHandle, int fence);
|
||||
bool Commit();
|
||||
bool TryHwComposition();
|
||||
bool ReallocLayerList();
|
||||
bool PrepareLayerList(layers::Layer* aContainer, const nsIntRect& aClip,
|
||||
|
@ -43,6 +43,10 @@ public:
|
||||
|
||||
virtual bool QueueBuffer(ANativeWindowBuffer* buf) = 0;
|
||||
|
||||
virtual void UpdateFBSurface(EGLDisplay dpy, EGLSurface sur) = 0;
|
||||
|
||||
virtual void SetFBReleaseFd(int fd) = 0;
|
||||
|
||||
float xdpi;
|
||||
uint32_t surfaceformat;
|
||||
};
|
||||
|
@ -196,6 +196,17 @@ GonkDisplayICS::QueueBuffer(ANativeWindowBuffer *buf)
|
||||
return !window->queueBuffer(window, buf);
|
||||
}
|
||||
|
||||
void
|
||||
GonkDisplayICS::UpdateFBSurface(EGLDisplay dpy, EGLSurface sur)
|
||||
{
|
||||
eglSwapBuffers(dpy, sur);
|
||||
}
|
||||
|
||||
void
|
||||
GonkDisplayICS::SetFBReleaseFd(int fd)
|
||||
{
|
||||
}
|
||||
|
||||
__attribute__ ((visibility ("default")))
|
||||
GonkDisplay*
|
||||
GetGonkDisplay()
|
||||
|
@ -46,6 +46,10 @@ public:
|
||||
|
||||
virtual bool QueueBuffer(ANativeWindowBuffer* handle);
|
||||
|
||||
virtual void UpdateFBSurface(EGLDisplay dpy, EGLSurface sur);
|
||||
|
||||
virtual void SetFBReleaseFd(int fd);
|
||||
|
||||
private:
|
||||
hw_module_t const* mModule;
|
||||
hwc_composer_device_t* mHwc;
|
||||
|
@ -272,6 +272,20 @@ GonkDisplayJB::QueueBuffer(ANativeWindowBuffer* buf)
|
||||
return success;
|
||||
}
|
||||
|
||||
void
|
||||
GonkDisplayJB::UpdateFBSurface(EGLDisplay dpy, EGLSurface sur)
|
||||
{
|
||||
StopBootAnimation();
|
||||
mBootAnimBuffer = nullptr;
|
||||
eglSwapBuffers(dpy, sur);
|
||||
}
|
||||
|
||||
void
|
||||
GonkDisplayJB::SetFBReleaseFd(int fd)
|
||||
{
|
||||
mFBSurface->setReleaseFenceFd(fd);
|
||||
}
|
||||
|
||||
__attribute__ ((visibility ("default")))
|
||||
GonkDisplay*
|
||||
GetGonkDisplay()
|
||||
|
@ -45,6 +45,10 @@ public:
|
||||
|
||||
virtual bool QueueBuffer(ANativeWindowBuffer* buf);
|
||||
|
||||
virtual void UpdateFBSurface(EGLDisplay dpy, EGLSurface sur);
|
||||
|
||||
virtual void SetFBReleaseFd(int fd);
|
||||
|
||||
bool Post(buffer_handle_t buf, int fence);
|
||||
|
||||
private:
|
||||
|
Loading…
Reference in New Issue
Block a user