Android ANativeWindow rendering screen

ANativeWindow is a C/C++ programming interface provided by Android NDK (Native Development Kit), which is used to interact with the underlying graphics system to implement functions such as image rendering and processing.


How to use: Use SurfaceView on the upper layer, pass the Surface of SurfaceView to the native layer, and convert the Surface to ANativeWindow in the native layer for rendering


For example, to render a solid-color page with ANativeWindow:

MainActivity:

public class MainActivity extends AppCompatActivity implements SurfaceHolder.Callback{

    static {
        System.loadLibrary("native-lib");
    }

    private ActivityMainBinding binding;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = ActivityMainBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());

        binding.surfaceView.getHolder().addCallback(this);
    }

    @Override
    public void surfaceCreated(@NonNull SurfaceHolder holder) {
    }

    @Override
    public void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width, int height) {
        setSurface(holder.getSurface());
    }

    @Override
    public void surfaceDestroyed(@NonNull SurfaceHolder holder) {
    }

    public native void setSurface(Surface surface);

}

It can be seen that the setSurface method is a native function, which is to pass the surface of the upper layer to the bottom layer


native layer:

extern "C"
JNIEXPORT void JNICALL
Java_xxx_MainActivity_setSurface(JNIEnv *env, jobject thiz, jobject surface) {

    ANativeWindow* window = ANativeWindow_fromSurface(env, surface);
    if (window == NULL) { // 处理无效的 ANativeWindow 对象
        return;
    }

    int32_t width = ANativeWindow_getWidth(window);
    int32_t height = ANativeWindow_getHeight(window);

    ANativeWindow_setBuffersGeometry(window, width, height, WINDOW_FORMAT_RGBA_8888);

    ANativeWindow_Buffer buffer;
    if (ANativeWindow_lock(window, &buffer, NULL) == 0) {
        uint32_t* pixels = static_cast<uint32_t*>(buffer.bits);
        for (int y = 0; y < height; y++) {
            for (int x = 0; x < width; x++) {
                pixels[y * buffer.stride + x] = 0xFFFF0000;
            }
        }
        ANativeWindow_unlockAndPost(window);
    }
    ANativeWindow_release(window); // 释放
}

①ANativeWindow_fromSurface():
Convert Android Surface object to ANativeWindow object for image rendering and processing.

②ANativeWindow_setBuffersGeometry():
It is used to set the buffer geometric properties of ANativeWindow . Tell the system how to allocate and manage the image buffer of ANativeWindow.

③ANativeWindow_lock():
used to lock the image buffer of ANativeWindow and obtain the pixel data of the operation buffer , and ensure data consistency and thread safety.

④ANativeWindow_unlockAndPost():
Unlock the image buffer of ANativeWindow , and notify the system that the image buffer has been modified for subsequent processing and refresh operations.


By using the ANativeWindow interface, developers can directly interact with the underlying graphics system to achieve high-performance image rendering and processing. It is widely used in fields such as game development, image processing and video playback.

Guess you like

Origin blog.csdn.net/weixin_47592544/article/details/130720607