Mir

Merge lp:~kdub/mir/workaround-qcom-display-request into lp:mir

Proposed by Kevin DuBois
Status: Merged
Approved by: Kevin DuBois
Approved revision: no longer in the source branch.
Merged at revision: 1337
Proposed branch: lp:~kdub/mir/workaround-qcom-display-request
Merge into: lp:mir
Diff against target: 67 lines (+33/-11)
2 files modified
src/platform/graphics/android/framebuffers.cpp (+15/-6)
tests/unit-tests/graphics/android/test_fb_simple_swapper.cpp (+18/-5)
To merge this branch: bzr merge lp:~kdub/mir/workaround-qcom-display-request
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Approve
Andreas Pokorny (community) Approve
Alan Griffiths Approve
Alexandros Frantzis (community) Needs Fixing
Daniel van Vugt Needs Fixing
Review via email: mp+201859@code.launchpad.net

Commit message

the stock qcom 8960 hwcomposer chokes on getDisplayAttributes if the submitted arrays are not at least size 6. I patched the qcom android 4.2 hwcomposer driver on the ubuntu touch images to work properly, but this causes us problems with in-the wild drivers, and the new 4.4 drivers. Make sure we always submit a larger-than-needed array to this function

Description of the change

the stock qcom 8960 hwcomposer chokes on getDisplayAttributes if the submitted arrays are not at least size 6. I patched the qcom android 4.2 hwcomposer driver on the ubuntu touch images to work properly, but this causes us problems with in-the wild drivers, and the new 4.4 drivers. Make sure we always submit a larger-than-needed array to this function

getDisplayAttributes() is supposed to work like eglChooseConfig, but the qcom implementation [1] breaks if the array is smaller than the array that surfaceflinger submits.

[1] https://android.googlesource.com/platform/hardware/qcom/display/+/master/msm8960/libhwcomposer/hwc.cpp line 527

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :

FAILED: Continuous integration, rev:1336
No commit message was specified in the merge proposal. Click on the following link and set the commit message (if you want a jenkins rebuild you need to trigger it yourself):
https://code.launchpad.net/~kdub/mir/workaround-qcom-display-request/+merge/201859/+edit-commit-message

http://jenkins.qa.ubuntu.com/job/mir-team-mir-development-branch-ci/671/
Executed test runs:
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-android-trusty-i386-build/652
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-clang-trusty-amd64-build/648
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-trusty-touch/255
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-team-mir-development-branch-trusty-amd64-ci/401
        deb: http://jenkins.qa.ubuntu.com/job/mir-team-mir-development-branch-trusty-amd64-ci/401/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-team-mir-development-branch-trusty-armhf-ci/405
        deb: http://jenkins.qa.ubuntu.com/job/mir-team-mir-development-branch-trusty-armhf-ci/405/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-builder-trusty-armhf/255
        deb: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-builder-trusty-armhf/255/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-runner-mako/273
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/3135

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/mir-team-mir-development-branch-ci/671/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
Kevin DuBois (kdub) wrote :

jenkins failure was just me not setting a commit msg.

Revision history for this message
Daniel van Vugt (vanvugt) wrote :

Looks good.

I'm just a little concerned about a pre-existing problem with test_fb_simple_swapper.cpp ...
It looks like display_attribute_handler() writes to the "values" array without any knowledge of the array length!?

review: Needs Information
Revision history for this message
Andreas Pokorny (andreas-pokorny) wrote :

> Looks good.
>
> I'm just a little concerned about a pre-existing problem with
> test_fb_simple_swapper.cpp ...
> It looks like display_attribute_handler() writes to the "values" array without
> any knowledge of the array length!?

The size is passed - currently unnamed it should check that that value is exactly 6 for now.

review: Needs Fixing
Revision history for this message
Kevin DuBois (kdub) wrote :

> Looks good.
>
> I'm just a little concerned about a pre-existing problem with
> test_fb_simple_swapper.cpp ...
> It looks like display_attribute_handler() writes to the "values" array without
> any knowledge of the array length!?

Yes, its ugly. However, the driver code does not implement this correctly, and to accommodate the driver, the testing code is just as bad as the driver code. This at least gives us the safety net that if this is changed incorrectly in the future, we have a comment, a segfault location, and a comment explaining why we had to accommodate this quirk.

Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

26 + int32_t size_values[sizeof(display_attribute_request) / sizeof (display_attribute_request[0])];

We really ought to have a lengthof function defined somewhere. Like:

    template <size_t Length, typename Element>
    constexpr size_t lengthof(Element (&)[Length]) { return Length; }

At least that fails to compile when passed a pointer.

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Andreas Pokorny (andreas-pokorny) wrote :

> > Looks good.
> >
> > I'm just a little concerned about a pre-existing problem with
> > test_fb_simple_swapper.cpp ...
> > It looks like display_attribute_handler() writes to the "values" array
> without
> > any knowledge of the array length!?
>
> Yes, its ugly. However, the driver code does not implement this correctly, and
> to accommodate the driver, the testing code is just as bad as the driver code.
> This at least gives us the safety net that if this is changed incorrectly in
> the future, we have a comment, a segfault location, and a comment explaining
> why we had to accommodate this quirk.

I was just afraid that we might not get a seg fault/test failure when we pass an array of wrong size.
So i thought the test should fail if we dont pass 6 elements - which we can only guess by the size parameter..

ok maybe valgrind would notice?

Revision history for this message
Kevin DuBois (kdub) wrote :

> I was just afraid that we might not get a seg fault/test failure when we pass
> an array of wrong size.
> So i thought the test should fail if we dont pass 6 elements - which we can
> only guess by the size parameter..

we don't have a size parameter to check, the function signature is
    int (*getDisplayAttributes)(struct hwc_composer_device_1* dev, int disp,
            uint32_t config, const uint32_t* attributes, int32_t* values);

you pass in the list of attributes you want in "attributes", and where you want those attributes filled in "values". The size is negotiated by the position of HWC_DISPLAY_NO_ATTRIBUTE in attributes.

Revision history for this message
Daniel van Vugt (vanvugt) wrote :

If the array is terminated by a HWC_DISPLAY_NO_ATTRIBUTE then we should be using ASSERT_EQ in place of EXPECT_EQ. That way the test will fail gracefully if anything changes, instead of segfaulting (or worse, failing with reads past the end of array).

review: Needs Fixing
Revision history for this message
Alexandros Frantzis (afrantzis) wrote :

53 + for(auto i = 2; i <= 6; i++)

Off by one error: i <= 5, or even i < 5 since I don't think HWC_DISPLAY_NO_ATTRIBUTE is expected to return a value (not that it matters for the code currently).

review: Needs Fixing
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

> 53 + for(auto i = 2; i <= 6; i++)
>
> Off by one error: i <= 5, or even i < 5 since I don't think
> HWC_DISPLAY_NO_ATTRIBUTE is expected to return a value (not that it matters
> for the code currently).

I guess we should be using named constants not magic numbers too.

Oh, and the principle that "the loop condition is the inverse of the termination invariant" says the condition should be "!=".

But given the above discussion, shouldn't this be:

for (auto p = values+2; *p != HWC_DISPLAY_NO_ATTRIBUTE; ++p)

review: Needs Fixing
Revision history for this message
Kevin DuBois (kdub) wrote :

this now scans for HWC_DISPLAY_NO_ATTRIBUTE and then checks the size, should be more robust.

Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

OK

review: Approve
Revision history for this message
Andreas Pokorny (andreas-pokorny) wrote :

ack

review: Approve
Revision history for this message
Kevin DuBois (kdub) wrote :

top, approving, seems people's concerns addressed.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/platform/graphics/android/framebuffers.cpp'
2--- src/platform/graphics/android/framebuffers.cpp 2014-01-10 03:59:43 +0000
3+++ src/platform/graphics/android/framebuffers.cpp 2014-01-17 17:18:01 +0000
4@@ -78,13 +78,22 @@
5 {
6 BOOST_THROW_EXCEPTION(std::runtime_error("could not determine hwc display config"));
7 }
8- static uint32_t size_request[3] = { HWC_DISPLAY_WIDTH,
9- HWC_DISPLAY_HEIGHT,
10- HWC_DISPLAY_NO_ATTRIBUTE};
11-
12- int size_values[2];
13+
14+ /* note: some drivers (qcom msm8960) choke if this is not the same size array
15+ as the one surfaceflinger submits */
16+ static uint32_t const display_attribute_request[] =
17+ {
18+ HWC_DISPLAY_WIDTH,
19+ HWC_DISPLAY_HEIGHT,
20+ HWC_DISPLAY_VSYNC_PERIOD,
21+ HWC_DISPLAY_DPI_X,
22+ HWC_DISPLAY_DPI_Y,
23+ HWC_DISPLAY_NO_ATTRIBUTE,
24+ };
25+
26+ int32_t size_values[sizeof(display_attribute_request) / sizeof (display_attribute_request[0])];
27 hwc_device->getDisplayAttributes(hwc_device.get(), HWC_DISPLAY_PRIMARY, primary_display_config,
28- size_request, size_values);
29+ display_attribute_request, size_values);
30
31 return {size_values[0], size_values[1]};
32 }
33
34=== modified file 'tests/unit-tests/graphics/android/test_fb_simple_swapper.cpp'
35--- tests/unit-tests/graphics/android/test_fb_simple_swapper.cpp 2014-01-10 03:59:43 +0000
36+++ tests/unit-tests/graphics/android/test_fb_simple_swapper.cpp 2014-01-17 17:18:01 +0000
37@@ -81,12 +81,25 @@
38 static int display_attribute_handler(struct hwc_composer_device_1*, int, uint32_t,
39 const uint32_t* attribute_list, int32_t* values)
40 {
41- EXPECT_EQ(attribute_list[0], HWC_DISPLAY_WIDTH);
42- EXPECT_EQ(attribute_list[1], HWC_DISPLAY_HEIGHT);
43- EXPECT_EQ(attribute_list[2], HWC_DISPLAY_NO_ATTRIBUTE);
44+ int i = 0;
45+ while(attribute_list[i] != HWC_DISPLAY_NO_ATTRIBUTE)
46+ {
47+ switch(attribute_list[i])
48+ {
49+ case HWC_DISPLAY_WIDTH:
50+ values[i] = display_width;
51+ break;
52+ case HWC_DISPLAY_HEIGHT:
53+ values[i] = display_height;
54+ break;
55+ default:
56+ break;
57+ }
58+ i++;
59+ }
60
61- values[0] = display_width;
62- values[1] = display_height;
63+ //the attribute list should be at least this long, as some qcom drivers always deref attribute_list[5]
64+ EXPECT_EQ(5, i);
65 return 0;
66 }
67 }

Subscribers

People subscribed via source and target branches