简体   繁体   English

Glium的高效2D渲染

[英]Efficient 2D rendering with Glium

I'm using Glium to do rendering for an emulator I'm writing. 我正在使用Glium为正在编写的仿真器进行渲染。 I've pieced together something that works (based on this example ) but I suspect that it's pretty inefficient. 我拼凑了一些可行的方法(基于此示例 ),但我怀疑它的效率很低。 Here's the relevant function: 相关功能如下:

fn update_screen(display: &Display, screen: &Rc<RefCell<NesScreen>>) {
    let target = display.draw();

    // Write screen buffer
    let borrowed_scr = screen.borrow();
    let mut buf = vec![0_u8; 256 * 240 * 3];
    buf.clone_from_slice(&borrowed_scr.screen_buffer[..]);
    let screen = RawImage2d::from_raw_rgb_reversed(buf, SCREEN_DIMENSIONS);
    glium::Texture2d::new(display, screen)
        .unwrap()
        .as_surface()
        .fill(&target, MagnifySamplerFilter::Nearest);

    target.finish().unwrap();
}

At a high level, this is what I'm doing: 在高层次上,这就是我正在做的:

  • Borrow NesScreen which contains the screen buffer, which is an array. 借用NesScreen ,它包含屏幕缓冲区,它是一个数组。
  • Clone the screen buffer into a vector 将屏幕缓冲区克隆到向量中
  • Create a texture from the vector data and render it 从矢量数据创建纹理并将其渲染

My suspicion is that cloning the entire screen buffer via clone_from_slice is really inefficient. 我的怀疑是,通过clone_from_slice克隆整个屏幕缓冲区确实效率很低。 The RawImage2d::from_raw_rgb_reversed function takes ownership of the vector passed into it, so I'm not sure how to do this in a way that avoids the clone. RawImage2d::from_raw_rgb_reversed函数获取传递给它的向量的所有权,所以我不确定如何避免克隆该如何做。

So, two questions: 因此,有两个问题:

  • Is this actually inefficient? 实际上效率低下吗? I don't have enough experience rendering stuff to know intuitively. 我没有足够的渲染知识来直觉了解。

  • If so, is there a more efficient way to do this? 如果是这样,是否有更有效的方法来做到这一点? I've scoured Glium quite a bit but there isn't much specific to 2D rendering. 我已经对Glium进行了很多搜索,但是2D渲染并没有太多特定之处。

This won't be a very good answer, but maybe a few things here could help you. 这将不是一个很好的答案,但是这里的一些内容可能会对您有所帮助。


First of all: is this really inefficient? 首先:这真的效率低下吗? That's really hard to say, especially the OpenGL part, as OpenGL performance depends a lot on when synchronization is required/requested. 这真的很难说,尤其是OpenGL部分,因为OpenGL性能在很大程度上取决于何时需要/请求同步。

As for the cloning of the screen buffer: you are merely copying 180kb, which is not too much. 至于屏幕缓冲区的克隆:您仅复制180kb,这并不过分。 I quickly benchmarked it on my machine and cloning a 180kb vector takes around 5µs, which is really not a lot. 我很快在计算机上对其进行了基准测试,克隆一个180kb的向量大约需要5µs,这的确不是很多。

Note that you can create a RawImage2d without using a method, because all fields are public. 请注意,您可以不使用任何方法来创建RawImage2d ,因为所有字段都是公共的。 This means that you can avoid the simple 5µs clone if you create a reversed vector yourself. 这意味着,如果您自己创建反向矢量,则可以避免简单的5µs克隆。 However , reversing the vector with the method glium uses is a lot slower than just cloning the vector; 但是使用glium使用的方法反转向量比克隆向量要慢得多。 on my machine it takes 170µs for a vector of the same length. 在我的机器上,相同长度的向量需要170µs。 This is probably still tolerable if you just want to achieve 60fps = 17ms per frame, but still not very nice. 如果您只想达到60fps = 17ms每帧,这可能仍然可以忍受 ,但仍然不是很好。

You could think about using the correct row ordering in your original array to avoid this problem. 您可以考虑在原始数组中使用正确的行顺序来避免此问题。 OR you could, instead of directly copying the texture to the framebuffer, just draw a fullscreen quad (one vertex for each screen corner) with the texture on it. 或者,您可以直接在其上绘制带有纹理的全屏四边形(每个屏幕角一个顶点),而不是直接将纹理复制到帧缓冲区。 Sure, then you need a mesh, a shader and all that stuff, but you could just "reverse" the image by tweaking the texture coordinates. 当然,您需要一个网格,一个着色器以及所有这些东西,但是您可以通过调整纹理坐标来“反转”图像。

Lastly, I unfortunately don't know a lot about the time the GPU takes to execute the OpenGL commands. 最后,不幸的是,我对GPU执行OpenGL命令所需的时间并不了解。 I'd guess that it's not optimal because OpenGL doesn't have a lot of room to schedule your commands, but has to execute them right away (forced synchronization). 这不是最佳选择,因为OpenGL没有太多时间来安排您的命令,而是必须立即执行它们(强制同步)。 But maybe that's not avoidable in your case. 但这也许在您的情况下是无法避免的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM