HwComposer - XePeleato/hisi_frameworks_native GitHub Wiki

This service has been a headache for nearly everyone, and we are going to fix it once and for good. I'll write a (not so) brief description of my research:

Including hwcomposer.hixxxx.so on AOSP or CM results in a bootloop, and we can retrieve the errors via logcat:

E Surface : queueBuffer: error queuing buffer to SurfaceTexture, -32

E [EGL-ERROR]: void __egl_platform_queue_buffer_android(mali_base_ctx_handle, egl_buffer*):1368: unable to queue buffer (0x0x7fa286ac10)

E [EGL-ERROR]: void __egl_platform_dequeue_buffer(egl_surface*):1731: failed to dequeue buffer from native window 0x7fa282b010; err = -32, buf = 0x0,max_allowed_dequeued_buffers 3

E Fence : merge: sync_merge("BootAnimation:1", 0, 42) returned an error: Bad file descriptor (-9)

E Region : Region::boolean_operation(op=7) invalid Rect={1,0,-2108275656,127}

Now, I have observed how some people tried to deal with those errors, but I have been unable to find someone who gathered all of them.

From my point of view, it's obvious that one error is triggering the rest of them, let's see what do they have in common:

  • Error (de)queueing buffer... : Those functions are defined in libs/gui/Surface.cpp and obviously if it isn't possible to queue a buffer, it will be impossible to dequeue it, this breaks the communication between HwComposer and SurfaceFlinger.

By taking a look at the disassembled functions, the EMUI's library calls a proprietary function called obtainRefreshDirty while queueing a buffer. The name of the function may mean that the function gets the region that needs to be updated because it's dirty (invalid), but that isn't causing the error directly, you'll understand it with the next error.

  • Region::boolean_operation(op=7) invalid Rect={1,0,-2108275656,127} : Apparently this error is trying to tell us that there's an invalid rectangle trying to be processed, and it's apparent that there's something really wrong, because a rectangle can't have a negative width. But let's see where does this come from, and we will do so by following the backtrace:

00 pc 000000000001d5bc /system/lib64/hw/hwcomposer.hi6210sft.so (_ZN17HwcPartialUpdates17UpdateSourceLayerEP11hwc_layer_1+72)

01 pc 0000000000019040 /system/lib64/hw/hwcomposer.hi6210sft.so (_ZN11HwcCompInfo17SetPartialUpdatesEP17HwcPartialUpdates+352)

This appears straight after that error in my logcat, and in order to know where it comes from we'll do the following:

We'll start with the function where it crashed, HwcPartialUpdates::UpdateSourceLayer, and look what instruction is calling Region::boolean_operation.

If you disassemble the function, chances are, you won't be able to find it, because it doesn't call it directly, but it calls Region::intersect(const Rect& rhs) (Hmm, remember what I said about getting a Dirty region? If a view is intersecting with a Dirty region, it's redrawed by Android) and Region::intersect(const Rect& rhs) calls Region::operation(const Rect& rhs, int op), and it calls Region::boolean_operation(int op, Region& dst, const Region& lhs, const Rect& rhs) that FINALLY calls Region::boolean_operation(int op, Region& dst, const Region& lhs, const Rect& rhs, int dx(0), int dy(0)).

So there we have it. Should we want to see what triggers HwcPartialUpdates::UpdateSourceLayer, the backtrace tells us that it is HwcCompInfo::SetPartialUpdates, and this one is called by what I think it is hwc_prepare(it isn't its exact name), but I am not sure.

Now that we know how it works, we can start playing with it. I have set ALOGEs on every function in order to have a look at the invalid rectangles, and after running logcat, I have found the following:

That rectangle is always generated by HwComposer, and it looks like this:

I hwcomposer: dump_layer:149: type=-1486720800, flags=00000000, handle=0x0, addr=00000000, tr=44340000, blend=44a00000, format=0,{0.000000,0.000000,0.000000,0.000000}, {1,0,-1479126536,127}

The type is always negative and 10 digits long, the handle is always 0x0 and the width is always negative and 10 digits long, however the value may vary.

After that message, this one appears:

E Region : bool_op rhs width: -1479126536 height: 127

That means that the value is negative from the start and it isn't altered on its way, but hey, I didn't receive any messages from the ALOGEs placed in Region::intersect or Region::operation (I do, but I just see valid operations, not the ones with negative values), anyway, we know that it ends there and that is comes from HwComposer.

Now the last one

  • E Fence : merge: sync_merge("BootAnimation:1", 0, 42) returned an error: Bad file descriptor (-9) This one at least gives us a more specific error, the function is declared in libs/ui/Fence.cpp.

I haven't looked much into it but I found this relation; It complains about a bad file descriptor, the full declaration of queueBuffer is int Surface::queueBuffer(android_native_buffer_t* buffer, int **fenceFd**) I don't believe this is a coincidence.

  • Things I have tried: I tried to modify boolean_operation so it would treat every negative rectangle as an INVALID_RECT (0, 0, -1, -1) but to no avail:

I hwcomposer: dump_layer:149: type=-1486720800, flags=00000000, handle=0x0, addr=00000000, tr=44340000, blend=44a00000, format=0,{0.000000,0.000000,0.000000,0.000000}, {1,0,-1479126536,127}

D hwcomposer: hwc_prepare:382: animation = 0

E Region : 1st bool_op rhs right: -1479126536 bottom: 127

E Region : It looks like the Rectangle is invalid, setting an appropriate value

E Region : Finished with the magic, let's see l/t/r/b 0 0 -1 -1

E Region : Rectangle successfully fixed!

E Region : 2nd bool_op Reached! let's check rhs, l/t/r/b 0 0 -1 -1 //After this it computes a couple of valid rectangles and then fails, but I have removed them because it isn't relevant. F libc : Fatal signal 11 (SIGSEGV), code 1, fault addr 0xff in tid 3801 (surfaceflinger)`

Also, when HwComposer crashes we notice that it can crash either as I explained above, or like this:

Last message before crashing: hwcomposer: setSource:99: areaInfo->mRect l/t/r/b 0/0/720/1280 Backtrace:

00 pc 000000000002b95c /system/lib64/hw/hwcomposer.hi6210sft.so (_ZN12Hi62xxCommon12detectLayersEPK11hwc_layer_1P8hwcLayeri+80)

01 pc 000000000002c494 /system/lib64/hw/hwcomposer.hi6210sft.so (_ZN12Hi62xxCommon15setNormalRegionEPK12HwcLayerInfoP8hwcLayerP8ade_rectiii+152)

02 pc 000000000002d858 /system/lib64/hw/hwcomposer.hi6210sft.so (_ZN13Hi62xxOverlay9setSourceEPK12HwcLayerInfoPK12_hwcAreaInfo+316)

03 pc 000000000001bb04 /system/lib64/hw/hwcomposer.hi6210sft.so (_ZN10HwcDisplay11SetHardwareEP11HwcCompInfo+1172)