Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pointer pin changes resolution along left/right edge #1879

Closed
Sequynth opened this issue Jun 2, 2020 · 13 comments
Closed

Pointer pin changes resolution along left/right edge #1879

Sequynth opened this issue Jun 2, 2020 · 13 comments
Labels

Comments

@Sequynth
Copy link
Contributor

Sequynth commented Jun 2, 2020

When rotating the view while the pointer pin is at the edge of the screen, the resolution of the pointer pin gradually gets very low, when the pointer pin approaches the center of the left screen edge. Also happens at the center of the right edge of the screen. Does not happen at top or bottom edge
20200603_003647
How to Reproduce
Move view away from actual position to get pointer pin; rotate the screen

Versions affected
SC 20.0
Android 6.0

@Sequynth Sequynth added the bug label Jun 2, 2020
@westnordost
Copy link
Member

😆 That is a funny bug. Needless to say, I cannot reproduce it, neither with Android 5 nor Android 7. Haven't tried with an Android 6 though. Which manufacturer?

@matkoniecz
Copy link
Member

Reproduced on Xiaomi with Android 6. What would be the first step to debug this?

I see nothing interesting in logs.
Maybe try to display this marker image while horizontal and try whatever static horizontal display is also mangled?

@westnordost
Copy link
Member

The code is in PointerPinView. It is a custom view that draws itself in onDraw. Since ony the pin and not the icon itself gets blurred, the relevant code is at line 97-103 :

        val size = min(width, height)
        val r = pinRotation

        pointerPin.setBounds(0,0, size, size)
        c.withRotation(r, width/2f, height/2f) {
            pointerPin.draw(c)
        }

Setting a breakpoint there might help, maybe check if size has a reasonable value. Maybe try if using canvas.width (instead of width) and height solves the problem.

@matkoniecz
Copy link
Member

matkoniecz commented Jun 3, 2020

canvas.width: 96 canvas.height: 96 width: 96 height: 96 size: 96 hold constant.

Things get weird with r around 450 and around 630.

Maybe try if using canvas.width (instead of width) and height solves the problem.

Sadly, it has not worked.

EDIT: And I get "Source code does not match the bytecode" on stepping into withRotation

@Sequynth
Copy link
Contributor Author

Sequynth commented Jun 3, 2020

Which manufacturer?

LG G4

@Sequynth Sequynth changed the title Pointer pin changes resolution along left/right corner Pointer pin changes resolution along left/right edge Jun 3, 2020
@westnordost
Copy link
Member

Maybe Android 6 doesn't handle angles >= 360° well. Maybe you could try % 360 the rotation.

@westnordost
Copy link
Member

If this is in degrees and all and not radians

@westnordost
Copy link
Member

Are you still trying it out, @matkoniecz ?

@matkoniecz
Copy link
Member

Maybe Android 6 doesn't handle angles >= 360° well. Maybe you could try % 360 the rotation.

Tried that (val r = pinRotation % 360), 270/90 is still problematic.

@matkoniecz
Copy link
Member

matkoniecz commented Jun 4, 2020

I unpacked

        c.withRotation(r, width/2f, height/2f) {
            pointerPin.draw(c)
        }

to mostly equivalent form - though one with 90 degree rotation applied everywhere and causing heaviest distortion.

        c.translate(width/2f, height/2f)
        c.rotate(90.0f)
        c.translate(-width/2f, -height/2f)
        pointerPin.draw(c)

the tricky part is that apparently broken rotate is just wrapper around nRotate(mNativeCanvasWrapper, degrees);. And nRotate appears to be a native library function if I am looking at this right.

@matkoniecz
Copy link
Member

matkoniecz commented Jun 4, 2020

I tracked it down and confirmed. It is https://stackoverflow.com/questions/36868790/blurry-image-after-canvas-rotate-only-in-android-6 https://issuetracker.google.com/issues/37096313 (found by Android Canvas nRotate Android 6 90 degree search).

Though not an answer, I have managed to find a workaround. This workaround relies on drawing the image onto a canvas, which is linked to a bitmap, which is then drawn onto the final, rotated canvas in the onDraw method.
(...)
with the important part occuring in the onMeasure method:

        if (innerGaugeBitmap != null){
            innerGaugeBitmap.recycle();
        }
        innerGaugeBitmap = Bitmap.createBitmap((int) width, (int) height, Bitmap.Config.ARGB_8888); // Gives LINT-warning draw-allocation, but no other way to upscale bitmaps exists.
        innerGaugeCanvas.setBitmap(innerGaugeBitmap);
        innerGaugeBitmap.eraseColor(Color.TRANSPARENT);
        innerGauge.draw(innerGaugeCanvas);

@westnordost
Copy link
Member

Ok, interesting. Will you do a fix, or shall I?

@matkoniecz
Copy link
Member

Feel free to fix! I am trying to finally finish one of my open PRs at this moment so I will be perfectly fine to be just a tester for this one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants