ANativeWindow scaling not working

2,361 views
Skip to first unread message

Alex H.

unread,
Oct 6, 2011, 10:12:46 AM10/6/11
to android-ndk
Hi!
(sorry for my buggy english)

I'm tying to use ANativeWindow, but keep having troubles with the
scaling. It works perfectly on a Asus Transformer (3.2), but not on
other devices and not even in the emulator (tried 2.3, 3.0, 3.1 and
3.2).

As of definition:

/*
* Change the format and size of the window buffers.
*
* The width and height control the number of pixels in the buffers,
not the
* dimensions of the window on screen. If these are different than the
* window's physical size, then it buffer will be scaled to match that
size
* when compositing it to the screen.
*
* For all of these parameters, if 0 is supplied then the window's base
* value will come back in force.
*/
int32_t ANativeWindow_setBuffersGeometry(ANativeWindow* window,
int32_t width, int32_t height, int32_t format);

The buffer is allocated correctly, but it is always displayed in the
same size as the buffer - without scaling.

I'll be very thankful for any ideas!

Greetings, Alex

gadget

unread,
Oct 19, 2012, 2:17:01 PM10/19/12
to andro...@googlegroups.com
yup... having the same problem. It seems that some devices and/or android versions (2.3) do not seem to honor the scaling specs!

Works as expected on:
Acer 500 / Tegra2 / 3.2
Motorola Xoom / Tegra2 / 4.0.4
Samsung Galaxy Nexus / SGX540 / 4.1

Does not work on:
HTC Thunderbolt / Adreno 205 / 2.3

Any workarounds out there?

gadget

unread,
Oct 23, 2012, 1:27:54 PM10/23/12
to andro...@googlegroups.com
workaround found!

credit goes to: MichalisB
http://stackoverflow.com/questions/7656783/how-can-i-automatically-scale-my-opengl-es-2-0-window

What one needs to do is follow the ANativeWindow_setBuffersGeometry() by a SurfaceHolder.setFixedSize() call
with identical width and height values. The SurfaceHolder is that which is associated with the SurfaceView, which was
used to create the ANativeWindow. This actually results in a slightly better performance (FPS-wise)
than just calling setBuffersGeometry() (assuming it works as expected)

gadget

unread,
Jun 11, 2013, 12:19:01 PM6/11/13
to andro...@googlegroups.com
hi joshua,

I think the problem lies in the following: NativeActivity does not create a SurfaceView, it does takeSurface, which is a bit different. What this does is it disables view hierarchy updates for your entire activity. It is for this same reason that you cannot create some sort of an AdView on top of NativeActivity. I would recommend copy/pasting the NativeActivity code (with some modifications, for example you will need to get your input via onTouch, onKey) and instead of takeSurface, create a proper SurfaceView. Then this trick should work. I can point you in the direction of some custom NativeActivities, if you would like.

As far as I can tell the specs for setBuffersGeometry are are not true for some driver/vendor combinations. I've communicated with the vendor for my particular problem device (Adreno 205), but this chip is old, so I don't think there is much stimulus to fix bugs for it.

mathimatica

unread,
Jun 27, 2013, 5:45:21 PM6/27/13
to andro...@googlegroups.com
Thank you very much for this information, i have had from time to time show native view's over my native activity, and i do this via pushing new activity overtop my native activity.  As for the use of setBuffersGeometry not always working, if this requires me to modify the native activity as you suggest, an example to look at would be much appriciated.  im using ndk version r8c, so its a tad old, perhaps some of the newer versions of the ndk actaully fix the use of setBuffersGeometry to work on all devices, or if it hasnt been fixed yet, perhaps in a future version, lets hope they get there act together (;.  Thanks again, and any cutom native activity would be great to see, thanks Gadget

Josh

Simon Tremblay

unread,
Sep 20, 2013, 12:20:05 PM9/20/13
to andro...@googlegroups.com
It would be nice to see some example since it seems that it isn't trivial to take original code of NativeActivity SDK class and modify it at our will.

Andy Coates

unread,
Feb 9, 2014, 11:15:36 AM2/9/14
to andro...@googlegroups.com
The way to fix this issue is to implement a SurfaceHolder.Callback2 like so:

public class TrueskateActivity extends NativeActivity implements SurfaceHolder.Callback2


The in your oncreate function after super.onCreate(icicle);:

        getWindow().takeSurface(null);

        mySurface = new SurfaceView(this);

        SurfaceHolder holder = mySurface.getHolder();

        holder.addCallback(this);

        setContentView(mySurface);


Then your holder callback:


    @Override

    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) 

    {

        super.surfaceChanged(holder, format, mWidthScale, mHeightScale);

        

    holder.setFixedSize(mWidthScale, mHeightScale);

    android.view.ViewGroup.LayoutParams lp = mySurface.getLayoutParams();

    lp.width = mWidth;

    lp.height = mHeight;

    mySurface.setLayoutParams(lp);        

    }  


Then some things to watch out for:

1. Do not get the actual screen size from c++ land but instead get it from Java.
2. Do not get the returned scaled surface size from egl because certain devices give wrong values back. Work out your actual scaled screen size from step 1
3. In the surfaceChanged callback this code is important:

because if you have a landscape game and you go to the lock screen the layout can get garbled.

This works on the 30 devices I have for reference so it's pretty safe to use and it works on all firmwares. And good luck :) Shared information make the world a better place!

spu...@gmail.com

unread,
Dec 17, 2014, 2:06:29 AM12/17/14
to andro...@googlegroups.com
Sorry for my English. Hello, I have the same problem with ANativeWindow_setBuffersGeometry, I try to show simple rgb buffer on android screen, for example I used NativeActivity without OpenGL (I used ANativeWindow_lock and draw direct to NativeWindows buffer), I don't know how mix Java code and ndk. Can anyone write a simple application that use ANativeWindow_setBuffersGeometry and holder.setFixedSize for example

воскресенье, 9 февраля 2014 г., 20:15:36 UTC+4 пользователь Andy Coates написал:
Reply all
Reply to author
Forward
0 new messages