hoffstadt / DearPyGui

Dear PyGui: A fast and powerful Graphical User Interface Toolkit for Python with minimal dependencies
https://dearpygui.readthedocs.io/en/latest/
MIT License
12.88k stars 671 forks source link

Rendering an image in dpg. plot takes too much time #2355

Open LiyueAnd opened 1 month ago

LiyueAnd commented 1 month ago

Version of Dear PyGui

 Version: 1.11.1 Operating System:Windows 11&Windows 10 

My Issue/Question

 To render a 1920 * 1280 pixel image in dpg. plot, it takes a huge amount of time (usually around 35ms) and it is difficult to achieve a frame rate of 30fps/s or higher. My graphics card is 3060ti. If I run it on a computer with poorer hardware or render a higher resolution image, the time will further increase. For better demonstration, I loop through the code to render the same image (in actual projects, I render each frame of the video), and the code and image attachments used will be placed in the front of the bottom 

To Reproduce

 Put my code and the provided images in the same directory, run the code, and the console will print the rendering time for each frame 

Expected behavior

 I hope to render the image data as quickly as possible after receiving it, and I hope to render a 1920 1280 pixel image with a time limit of less than 10ms ,I hope to render the image data as quickly as possible after receiving it, and I hope to render a 1920 1280 pixel image with a time limit of less than 10ms Also, it is hoped that add_dynamic_texture can receive the original pixel data: [R, G, B, A], rather than having to convert it to floatation: [R/255, G/255, B/255, A/255] in order to be received Because most third-party libraries currently return image data in RGB format, converting it to floating-point data will increase preprocessing time 

Screenshots/Video

Snipaste_2024-07-07_18-10-22

Standalone, minimal, complete and verifiable example

img

import time import dearpygui.dearpygui as dpg

dpg.create_context() dpg.create_viewport(title='Visualization Tool') with dpg.window(no_scrollbar=True, delay_search=True, no_move=False, label="main", width=2000, height=1500) as window1:

w, h, _, d = dpg.load_image("./img.png")

with dpg.texture_registry(show=False) as dynamic_texture_registry:
    transparent_background = dpg.add_dynamic_texture(w,  h,d)

with dpg.plot(no_title=True, no_menus=True, no_child=True,delay_search=False,width=900,height=600) as image_plot:
    plot_x = dpg.add_plot_axis(dpg.mvXAxis, no_tick_labels=True, no_tick_marks=True, no_gridlines=True, )
    with dpg.plot_axis(dpg.mvYAxis, no_tick_labels=True, no_tick_marks=True, no_gridlines=True,
                       invert=True) as plot_y:
        dpg.add_image_series(transparent_background, [0, h], [w, 0])
dpg.add_button(label="start",callback=lambda :mystart())

def mystart():
    while True:
        tt1=time.time()
        dpg.configure_item(transparent_background,default_value=d)
        tt2=time.time()
        print("渲染耗时",tt2-tt1)

dpg.setup_dearpygui() dpg.show_viewport() dpg.start_dearpygui() dpg.destroy_context()

LiyueAnd commented 1 month ago

很高兴我的问题得到了解决,我看了bug列表中的https://github.com/hoffstadt/DearPyGui/issues/2124,只要将add_dynamic_texture换为dpg.add_raw_texture并将格式稍微修改,就能达到30fps,谢谢 !

axeldavy commented 1 month ago

I face the same issue.

I want to interact with a large image, and I figured out using a plot would be a good fit, using several textures.

I found out that just having the textures on the plot would make everything extremely slow when the textures are dynamic or raw, even if the content of the textures is not updated at all.

However when the textures are static, the speed is greatly improved. Sadly there is a non negligible overhead I can measure of creating the textures which slow down rendering, despite creating the textures in a callback (But I guess it is expected of opengl. Deleting and creating a lot of textures frequently is not expected to be performant).

I suspect the reason dynamic and raw textures are slow is that the content would be uploaded synchronously every frame (even if the content wasn't changed). But that's just a wild guess.

axeldavy commented 1 month ago

The proposed test code measures the time to update a dynamic texture (configure_item) and not the frame rate. It seems that the pull request doesn't impact the speed of configure_item. I suspect the reason behind the slow performance might be that the internal copy could be optimized better (ToFloatVect).

Using the code with a numpy array and a raw texture, the speed of set_value is a matter of microseconds. The frame rate I achieve is a full 200 fps with vsync off.

My own issue I described above is fixed by #2365, but this PR has no impact on the test code of this issue as the texture content is changed every frame.