From f45d0b5903c6a1ea9eda86e25df8d3f9676eb8d0 Mon Sep 17 00:00:00 2001 From: andy840119 Date: Mon, 11 Oct 2021 10:48:55 +0800 Subject: [PATCH] should save shaders into shared data instead because frame buffer is highly related to shader. it might cause not found issue if changing frame buffer dictionary and drawing at the same time. --- .../Graphics/MultiShaderBufferedDrawNode.cs | 17 +++-------------- .../MultiShaderBufferedDrawNodeSharedData.cs | 17 ++++++++++++----- 2 files changed, 15 insertions(+), 19 deletions(-) diff --git a/osu.Framework.Font/Graphics/MultiShaderBufferedDrawNode.cs b/osu.Framework.Font/Graphics/MultiShaderBufferedDrawNode.cs index 03be370..17e466f 100644 --- a/osu.Framework.Font/Graphics/MultiShaderBufferedDrawNode.cs +++ b/osu.Framework.Font/Graphics/MultiShaderBufferedDrawNode.cs @@ -20,8 +20,6 @@ public class MultiShaderBufferedDrawNode : BufferedDrawNode protected new MultiShaderBufferedDrawNodeSharedData SharedData => (MultiShaderBufferedDrawNodeSharedData)base.SharedData; - private IShader[] shaders = { }; - private readonly double loadTime; public MultiShaderBufferedDrawNode(IBufferedDrawable source, DrawNode child, MultiShaderBufferedDrawNodeSharedData sharedData) @@ -33,19 +31,13 @@ public MultiShaderBufferedDrawNode(IBufferedDrawable source, DrawNode child, Mul public override void ApplyState() { base.ApplyState(); - - if (shaders.SequenceEqual(Source.Shaders)) - return; - - // should clear buffer if property changed because might be shader amount changed. - shaders = Source.Shaders.ToArray(); - SharedData.CreateDefaultFrameBuffers(shaders); + SharedData.UpdateFrameBuffers(Source.Shaders.ToArray()); } protected override long GetDrawVersion() { // if contains shader that need to apply time, then need to force run populate contents in each frame. - if (ContainTimePropertyShader(shaders)) + if (ContainTimePropertyShader(SharedData.Shaders)) { ResetDrawVersion(); } @@ -91,10 +83,6 @@ protected override void DrawContents() { foreach (var frameBuffer in drawFrameBuffers) { - // got no idea why happened. - if (frameBuffer.Texture == null) - break; - DrawFrameBuffer(frameBuffer, DrawRectangle, Color4.White); } } @@ -107,6 +95,7 @@ protected override void DrawContents() private void drawFrameBuffer() { + var shaders = SharedData.Shaders; if (!shaders.Any()) return; diff --git a/osu.Framework.Font/Graphics/MultiShaderBufferedDrawNodeSharedData.cs b/osu.Framework.Font/Graphics/MultiShaderBufferedDrawNodeSharedData.cs index a75db32..2ab2e50 100644 --- a/osu.Framework.Font/Graphics/MultiShaderBufferedDrawNodeSharedData.cs +++ b/osu.Framework.Font/Graphics/MultiShaderBufferedDrawNodeSharedData.cs @@ -3,7 +3,6 @@ using System; using System.Collections.Generic; -using System.IO; using System.Linq; using System.Reflection; using osu.Framework.Graphics.OpenGL; @@ -17,6 +16,8 @@ public class MultiShaderBufferedDrawNodeSharedData : BufferedDrawNodeSharedData { private readonly Dictionary shaderBuffers = new Dictionary(); + public IShader[] Shaders => shaderBuffers.Keys.ToArray(); + private readonly RenderbufferInternalFormat[] formats; public MultiShaderBufferedDrawNodeSharedData(RenderbufferInternalFormat[] formats = null, bool pixelSnapping = false) @@ -25,11 +26,12 @@ public MultiShaderBufferedDrawNodeSharedData(RenderbufferInternalFormat[] format this.formats = formats; } - public void CreateDefaultFrameBuffers(IShader[] shaders) + public void UpdateFrameBuffers(IShader[] shaders) { if (shaderBuffers.Keys.SequenceEqual(shaders)) return; + // collect all frame buffer that needs to be disposed. var disposedFrameBuffer = shaderBuffers.Values.ToArray(); shaderBuffers.Clear(); @@ -66,7 +68,7 @@ public FrameBuffer GetSourceFrameBuffer(IShader shader) return CurrentEffectBuffer; if (!shaderBuffers.ContainsKey(fromShader)) - throw new DirectoryNotFoundException(); + throw new KeyNotFoundException(); return shaderBuffers[fromShader]; } @@ -74,7 +76,7 @@ public FrameBuffer GetSourceFrameBuffer(IShader shader) public FrameBuffer GetTargetFrameBuffer(IShader shader) { if (!shaderBuffers.ContainsKey(shader)) - throw new DirectoryNotFoundException(); + throw new KeyNotFoundException(); return shaderBuffers[shader]; } @@ -90,7 +92,12 @@ public void UpdateBuffer(IShader shader, FrameBuffer frameBuffer) public FrameBuffer[] GetDrawFrameBuffers() => shaderBuffers.Where(x => { - var shader = x.Key; + var (shader, frameBuffer) = x; + + // should not render disposed or not created frame buffer. + if (frameBuffer.Texture == null) + return false; + if (shader is IStepShader stepShader) return stepShader.StepShaders.Any() && stepShader.Draw;