From be67b039d691348880a4a885f82667485cd47e83 Mon Sep 17 00:00:00 2001 From: Flamefire Date: Sat, 20 Sep 2014 16:01:10 +0200 Subject: [PATCH] Unify and improve texture updating (Do not create new references) --- Vocaluxe/Base/CDraw.cs | 9 +-- Vocaluxe/Lib/Draw/CDirect3D.cs | 25 ------ Vocaluxe/Lib/Draw/CDrawBase.cs | 81 ++++++++++++------- Vocaluxe/Lib/Draw/CDrawWinForm.cs | 16 +--- Vocaluxe/Lib/Draw/COpenGL.cs | 19 ----- Vocaluxe/Lib/Draw/IDraw.cs | 3 +- .../Lib/Video/Acinerella/CDecoderThread.cs | 5 +- Vocaluxe/Lib/Webcam/CAForgeNet.cs | 5 +- VocaluxeLib/Draw/CTextureRef.cs | 8 ++ 9 files changed, 74 insertions(+), 97 deletions(-) diff --git a/Vocaluxe/Base/CDraw.cs b/Vocaluxe/Base/CDraw.cs index 7c5cd4e2..5c5b97cc 100644 --- a/Vocaluxe/Base/CDraw.cs +++ b/Vocaluxe/Base/CDraw.cs @@ -165,14 +165,9 @@ namespace Vocaluxe.Base return _Draw.EnqueueTexture(w, h, data); } - public static bool UpdateTexture(CTextureRef texture, int w, int h, byte[] data) + public static void UpdateTexture(CTextureRef texture, int w, int h, byte[] data) { - return _Draw.UpdateTexture(texture, w, h, data); - } - - public static bool UpdateOrAddTexture(ref CTextureRef texture, int w, int h, byte[] data) - { - return _Draw.UpdateOrAddTexture(ref texture, w, h, data); + _Draw.UpdateTexture(texture, w, h, data); } public static void RemoveTexture(ref CTextureRef texture) diff --git a/Vocaluxe/Lib/Draw/CDirect3D.cs b/Vocaluxe/Lib/Draw/CDirect3D.cs index 9ed511ae..55823166 100644 --- a/Vocaluxe/Lib/Draw/CDirect3D.cs +++ b/Vocaluxe/Lib/Draw/CDirect3D.cs @@ -601,31 +601,6 @@ namespace Vocaluxe.Lib.Draw texture.D3DTexture.UnlockRectangle(0); } - /// - /// Updates the data of a texture - /// - /// The texture to update - /// - /// - /// A byte array containing the new texture's data - /// True if succeeded - public override bool UpdateTexture(CTextureRef textureRef, int w, int h, byte[] data) - { - CD3DTexture texture; - if (!_GetTexture(textureRef, out texture)) - return false; - if (texture.DataSize.Width != w || texture.DataSize.Height != h) - { - if (texture.W2 > w || texture.H2 > h) - return false; // Texture memory to small - if (texture.W2 * 0.9 < w || texture.H2 * 0.9 < h) - return false; // Texture memory to big - texture.DataSize = new Size(w, h); - } - _WriteDataToTexture(texture, data); - return true; - } - #region drawing /// /// Draws a texture diff --git a/Vocaluxe/Lib/Draw/CDrawBase.cs b/Vocaluxe/Lib/Draw/CDrawBase.cs index 9fe49f16..28b7f44c 100644 --- a/Vocaluxe/Lib/Draw/CDrawBase.cs +++ b/Vocaluxe/Lib/Draw/CDrawBase.cs @@ -173,7 +173,7 @@ namespace Vocaluxe.Lib.Draw /// /// /// - protected TTextureType _CreateTexture(Size dataSize, byte[] data) + private TTextureType _CreateAndFillTexture(Size dataSize, byte[] data) { TTextureType texture = _CreateTexture(dataSize); _WriteDataToTexture(texture, data); @@ -187,7 +187,7 @@ namespace Vocaluxe.Lib.Draw /// /// /// - protected TTextureType _CreateTexture(Size dataSize, IntPtr data) + private TTextureType _CreateAndFillTexture(Size dataSize, IntPtr data) { TTextureType texture = _CreateTexture(dataSize); _WriteDataToTexture(texture, data); @@ -326,7 +326,7 @@ namespace Vocaluxe.Lib.Draw //Fill the new Bitmap with the texture data BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); - texture = _CreateTexture(new Size(w, h), bmpData.Scan0); + texture = _CreateAndFillTexture(new Size(w, h), bmpData.Scan0); bmp.UnlockBits(bmpData); } finally @@ -341,7 +341,7 @@ namespace Vocaluxe.Lib.Draw public CTextureRef AddTexture(int w, int h, byte[] data) { - TTextureType texture = _CreateTexture(new Size(w, h), data); + TTextureType texture = _CreateAndFillTexture(new Size(w, h), data); return _GetTextureReference(w, h, texture); } @@ -398,21 +398,37 @@ namespace Vocaluxe.Lib.Draw /// /// Updates the data of a texture /// - /// The texture to update + /// The texture to update /// /// /// A byte array containing the new texture's data /// True if succeeded - public abstract bool UpdateTexture(CTextureRef texture, int w, int h, byte[] data); - - public bool UpdateOrAddTexture(ref CTextureRef texture, int w, int h, byte[] data) + public void UpdateTexture(CTextureRef textureRef, int w, int h, byte[] data) { - if (!UpdateTexture(texture, w, h, data)) + TTextureType texture; + if (_GetTexture(textureRef, out texture)) + return; + bool reuseTexture = true; + if (texture.DataSize.Width != w || texture.DataSize.Height != h) { - RemoveTexture(ref texture); - texture = AddTexture(w, h, data); + if (texture.W2 > w || texture.H2 > h) + reuseTexture = false; // Texture memory to small + else if (texture.W2 * 0.9 < w || texture.H2 * 0.9 < h) + reuseTexture = false; // Texture memory to big + else + texture.DataSize = new Size(w, h); } - return true; + if (!reuseTexture) + { + _DisposeTexture(texture); + texture = _CreateAndFillTexture(new Size(w, h), data); + lock (_Textures) + { + _Textures[textureRef.ID] = texture; + } + } + else + _WriteDataToTexture(texture, data); } protected bool _GetTexture(CTextureRef textureRef, out TTextureType texture) @@ -428,31 +444,40 @@ namespace Vocaluxe.Lib.Draw } } + /// + /// Decreases the RefCount of a texture and disposes it if necessary + /// + /// + private void _DisposeTexture(TTextureType texture) + { + if (texture != null && --texture.RefCount <= 0) + { + if (texture.TexturePath != null) + _TextureCache.Remove(texture.TexturePath); + texture.Dispose(); + _TextureCount--; + } + } + /// /// Removes a texture from the Vram /// - /// The texture to be removed - public void RemoveTexture(ref CTextureRef texture) + /// The texture to be removed + public void RemoveTexture(ref CTextureRef textureRef) { - if (texture == null) + if (textureRef == null) return; lock (_Textures) { TTextureType t; - if (_Textures.TryGetValue(texture.ID, out t)) + if (_Textures.TryGetValue(textureRef.ID, out t)) { - if (t != null && --t.RefCount <= 0) - { - if (t.TexturePath != null) - _TextureCache.Remove(t.TexturePath); - t.Dispose(); - _TextureCount--; - } - _Textures.Remove(texture.ID); + _DisposeTexture(t); + _Textures.Remove(textureRef.ID); } - texture.ID = -1; + textureRef.ID = -1; } - texture = null; + textureRef = null; } private void _CheckQueue() @@ -465,7 +490,7 @@ namespace Vocaluxe.Lib.Draw if (!_Textures.ContainsKey(q.TextureID)) continue; - TTextureType texture = _CreateTexture(q.DataSize, q.Data); + TTextureType texture = _CreateAndFillTexture(q.DataSize, q.Data); texture.RefCount = 1; //Currently no more than 1 reference to queued textures is possible _Textures[q.TextureID] = texture; } @@ -566,7 +591,7 @@ namespace Vocaluxe.Lib.Draw } } - protected void _ToggleFullScreen() + private void _ToggleFullScreen() { if (!_Fullscreen) _EnterFullScreen(); diff --git a/Vocaluxe/Lib/Draw/CDrawWinForm.cs b/Vocaluxe/Lib/Draw/CDrawWinForm.cs index ee09c54c..7e9260a2 100644 --- a/Vocaluxe/Lib/Draw/CDrawWinForm.cs +++ b/Vocaluxe/Lib/Draw/CDrawWinForm.cs @@ -343,7 +343,7 @@ namespace Vocaluxe.Lib.Draw using (var bmp = new Bitmap(texturePath)) { texture = AddTexture(bmp); - _TextureCache.Add(texturePath,texture); + _TextureCache.Add(texturePath, texture); } return texture; } @@ -382,7 +382,7 @@ namespace Vocaluxe.Lib.Draw } } - public bool UpdateTexture(CTextureRef texture, int w, int h, byte[] data) + public void UpdateTexture(CTextureRef texture, int w, int h, byte[] data) { if (_TextureExists(texture)) { @@ -390,19 +390,7 @@ namespace Vocaluxe.Lib.Draw ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb); Marshal.Copy(data, 0, bmpData.Scan0, data.Length); _Bitmaps[texture.ID].UnlockBits(bmpData); - return true; } - return false; - } - - public bool UpdateOrAddTexture(ref CTextureRef texture, int w, int h, byte[] data) - { - if (!UpdateTexture(texture, w, h, data)) - { - RemoveTexture(ref texture); - texture = AddTexture(w, h, data); - } - return true; } public void DrawTexture(CTextureRef texture) diff --git a/Vocaluxe/Lib/Draw/COpenGL.cs b/Vocaluxe/Lib/Draw/COpenGL.cs index 8cfb9aa4..c89ce657 100644 --- a/Vocaluxe/Lib/Draw/COpenGL.cs +++ b/Vocaluxe/Lib/Draw/COpenGL.cs @@ -434,25 +434,6 @@ namespace Vocaluxe.Lib.Draw GL.BindTexture(TextureTarget.Texture2D, 0); } - public override bool UpdateTexture(CTextureRef textureRef, int w, int h, byte[] data) - { - COGLTexture texture; - if (_GetTexture(textureRef, out texture)) - return false; - if (texture.DataSize.Width != w || texture.DataSize.Height != h) - { - if (texture.W2 > w || texture.H2 > h) - return false; // Texture memory to small - if (texture.W2 * 0.9 < w || texture.H2 * 0.9 < h) - return false; // Texture memory to big - texture.DataSize = new Size(w, h); - } - - _WriteDataToTexture(texture, data); - - return true; - } - #region drawing public override void DrawTexture(CTextureRef textureRef, SRectF rect, SColorF color, bool mirrored = false) { diff --git a/Vocaluxe/Lib/Draw/IDraw.cs b/Vocaluxe/Lib/Draw/IDraw.cs index 44653e41..09a0aa0e 100644 --- a/Vocaluxe/Lib/Draw/IDraw.cs +++ b/Vocaluxe/Lib/Draw/IDraw.cs @@ -41,8 +41,7 @@ namespace Vocaluxe.Lib.Draw CTextureRef AddTexture(Bitmap bitmap); CTextureRef AddTexture(int w, int h, byte[] data); CTextureRef EnqueueTexture(int w, int h, byte[] data); - bool UpdateTexture(CTextureRef texture, int w, int h, byte[] data); - bool UpdateOrAddTexture(ref CTextureRef texture, int w, int h, byte[] data); + void UpdateTexture(CTextureRef texture, int w, int h, byte[] data); void RemoveTexture(ref CTextureRef texture); // Basic Draw Methods diff --git a/Vocaluxe/Lib/Video/Acinerella/CDecoderThread.cs b/Vocaluxe/Lib/Video/Acinerella/CDecoderThread.cs index ead40da9..78707644 100644 --- a/Vocaluxe/Lib/Video/Acinerella/CDecoderThread.cs +++ b/Vocaluxe/Lib/Video/Acinerella/CDecoderThread.cs @@ -206,7 +206,10 @@ namespace Vocaluxe.Lib.Video.Acinerella CFramebuffer.CFrame curFrame = _FindFrame(time); if (curFrame != null) { - CDraw.UpdateOrAddTexture(ref frame, _Width, _Height, curFrame.Data); + if (frame == null) + frame = CDraw.AddTexture(_Width, _Height, curFrame.Data); + else + CDraw.UpdateTexture(frame, _Width, _Height, curFrame.Data); if (!_Paused) curFrame.SetRead(); time = curFrame.Time; diff --git a/Vocaluxe/Lib/Webcam/CAForgeNet.cs b/Vocaluxe/Lib/Webcam/CAForgeNet.cs index 723eddc0..0d6e9918 100644 --- a/Vocaluxe/Lib/Webcam/CAForgeNet.cs +++ b/Vocaluxe/Lib/Webcam/CAForgeNet.cs @@ -207,7 +207,10 @@ namespace Vocaluxe.Lib.Webcam { if (_Data != null && _Data.Length == _Width * _Height * 4 && _NewFrameAvailable) { - CDraw.UpdateOrAddTexture(ref frame, _Width, _Height, _Data); + if (frame == null) + frame = CDraw.AddTexture(_Width, _Height, _Data); + else + CDraw.UpdateTexture(frame, _Width, _Height, _Data); _NewFrameAvailable = false; return true; } diff --git a/VocaluxeLib/Draw/CTextureRef.cs b/VocaluxeLib/Draw/CTextureRef.cs index 3bc6526a..886da3a9 100644 --- a/VocaluxeLib/Draw/CTextureRef.cs +++ b/VocaluxeLib/Draw/CTextureRef.cs @@ -56,6 +56,14 @@ namespace VocaluxeLib.Draw Rect = new SRectF(0f, 0f, origSize.Width, origSize.Height, 0f); } + public void CopyFieldsFrom(CTextureRef other) + { + ID = other.ID; + OrigSize = other.OrigSize; + Rect = other.Rect; + Color = other.Color; + } + ~CTextureRef() { if (ID >= 0)