0

我正在使用 SharpDX 基本上在 directX 进程上呈现浏览器(铬)输出缓冲区。

过程相对简单,我截取 CEF 缓冲区(通过覆盖 OnPaint 方法)并将其写入纹理 2D。

代码比较简单:

纹理创建:

public void BuildTextureWrap() {
    var oldTexture = texture;

    texture = new D3D11.Texture2D(DxHandler.Device, new D3D11.Texture2DDescription() {
        Width = overlay.Size.Width,
        Height = overlay.Size.Height,
        MipLevels = 1,
        ArraySize = 1,
        Format = DXGI.Format.B8G8R8A8_UNorm,
        SampleDescription = new DXGI.SampleDescription(1, 0),
        Usage = D3D11.ResourceUsage.Default,
        BindFlags = D3D11.BindFlags.ShaderResource,
        CpuAccessFlags = D3D11.CpuAccessFlags.None,
        OptionFlags = D3D11.ResourceOptionFlags.None,
    });

    var view = new D3D11.ShaderResourceView(
        DxHandler.Device,
        texture,
        new D3D11.ShaderResourceViewDescription {
            Format = texture.Description.Format,
            Dimension = D3D.ShaderResourceViewDimension.Texture2D,
            Texture2D = { MipLevels = texture.Description.MipLevels },
        }
    );

    textureWrap = new D3DTextureWrap(view, texture.Description.Width, texture.Description.Height);

    if (oldTexture != null) {
        obsoleteTextures.Add(oldTexture);
    }
}

那段代码在开始和调整大小时执行。

现在当 CEF OnDraw 我基本上将他们的缓冲区复制到纹理:

var destinationRegion = new D3D11.ResourceRegion {
    Top = Math.Min(r.dirtyRect.y, texDesc.Height),
    Bottom = Math.Min(r.dirtyRect.y + r.dirtyRect.height, texDesc.Height),
    Left = Math.Min(r.dirtyRect.x, texDesc.Width),
    Right = Math.Min(r.dirtyRect.x + r.dirtyRect.width, texDesc.Width),
    Front = 0,
    Back = 1,
};

// Draw to the target
var context = targetTexture.Device.ImmediateContext;
context.UpdateSubresource(targetTexture, 0, destinationRegion, sourceRegionPtr, rowPitch, depthPitch);

还有更多代码,但基本上这只是相关的部分。整个过程一直有效,直到 OnDraw 频繁发生。

显然,如果我强制 CEF 频繁绘制,整个主机进程就会死掉。这发生在UpdateSubresource.

所以我的问题是,有没有另一种更安全的方法来做到这一点?(经常更新纹理)

4

1 回答 1

1

这个问题的解决方法比较简单,但一开始并不那么明显。

我只是在渲染循环中移动了负责更新纹理的代码,并保持内部缓冲区指针缓存。

于 2021-10-22T01:01:07.920 回答