static public ImageGlPlugin GetImageGlPlugin(ImageBuffer imageToGetDisplayListFor, bool createAndUseMipMaps, bool TextureMagFilterLinear = true) { ImageGlPlugin plugin; imagesWithCacheData.TryGetValue(imageToGetDisplayListFor.GetBuffer(), out plugin); using (TimedLock.Lock(glDataNeedingToBeDeleted, "GetImageGlPlugin")) { // We run this in here to ensure that we are on the correct thread and have the correct // glcontext realized. for (int i = glDataNeedingToBeDeleted.Count - 1; i >= 0; i--) { int textureToDelete = glDataNeedingToBeDeleted[i].glTextureHandle; if (glDataNeedingToBeDeleted[i].refreshCountCreatedOn == currentGlobalRefreshCount) { GL.DeleteTextures(1, ref textureToDelete); } glDataNeedingToBeDeleted.RemoveAt(i); } } #if ON_IMAGE_CHANGED_ALWAYS_CREATE_IMAGE if (plugin != null && (imageToGetDisplayListFor.ChangedCount != plugin.imageUpdateCount || plugin.glData.refreshCountCreatedOn != currentGlobalRefreshCount)) { int textureToDelete = plugin.GLTextureHandle; if (plugin.glData.refreshCountCreatedOn == currentGlobalRefreshCount) { GL.DeleteTextures(1, ref textureToDelete); } plugin.glData.glTextureHandle = 0; imagesWithCacheData.Remove(imageToGetDisplayListFor.GetBuffer()); plugin = null; } if (plugin == null) { ImageGlPlugin newPlugin = new ImageGlPlugin(); imagesWithCacheData.Add(imageToGetDisplayListFor.GetBuffer(), newPlugin); newPlugin.createdWithMipMaps = createAndUseMipMaps; newPlugin.CreateGlDataForImage(imageToGetDisplayListFor, TextureMagFilterLinear); newPlugin.imageUpdateCount = imageToGetDisplayListFor.ChangedCount; newPlugin.glData.refreshCountCreatedOn = currentGlobalRefreshCount; return newPlugin; } #else if (plugin == null) { ImageGlPlugin newPlugin = new ImageGlPlugin(); imagesWithCacheData.Add(imageToGetDisplayListFor.GetBuffer(), newPlugin); newPlugin.createdWithMipMaps = createAndUseMipMaps; newPlugin.CreateGlDataForImage(imageToGetDisplayListFor, TextureMagFilterLinear); newPlugin.imageUpdateCount = imageToGetDisplayListFor.ChangedCount; newPlugin.refreshCountCreatedOn = currentGlobalRefreshCount; return newPlugin; } if(imageToGetDisplayListFor.ChangedCount != plugin.imageUpdateCount || plugin.refreshCountCreatedOn != currentGlobalRefreshCount) { plugin.imageUpdateCount = imageToGetDisplayListFor.ChangedCount; plugin.refreshCountCreatedOn = currentGlobalRefreshCount; GL.BindTexture(TextureTarget.Texture2D, plugin.GLTextureHandle); // Create the texture switch (imageToGetDisplayListFor.BitDepth) { case 8: GL.TexSubImage2D(TextureTarget.Texture2D, 0, 0, 0, imageToGetDisplayListFor.Width, imageToGetDisplayListFor.Height, PixelFormat.Luminance, PixelType.UnsignedByte, imageToGetDisplayListFor.GetBuffer()); break; case 24: // our bitmaps are not padded and GL is having a problem with them so don't use 24 bit unless you fix this. GL.TexSubImage2D(TextureTarget.Texture2D, 0, 0, 0, imageToGetDisplayListFor.Width, imageToGetDisplayListFor.Height, PixelFormat.Bgr, PixelType.UnsignedByte, imageToGetDisplayListFor.GetBuffer()); break; case 32: GL.TexSubImage2D(TextureTarget.Texture2D, 0, 0, 0, imageToGetDisplayListFor.Width, imageToGetDisplayListFor.Height, PixelFormat.Bgra, PixelType.UnsignedByte, imageToGetDisplayListFor.GetBuffer()); break; default: throw new NotImplementedException(); } if (plugin.createdWithMipMaps) { if (GLMajorVersion < 3) { switch (imageToGetDisplayListFor.BitDepth) { case 32: { ImageBuffer sourceImage = new ImageBuffer(imageToGetDisplayListFor); ImageBuffer tempImage = new ImageBuffer(sourceImage.Width / 2, sourceImage.Height / 2, 32, new BlenderBGRA()); tempImage.NewGraphics2D().Render(sourceImage, 0, 0, 0, .5, .5); int mipLevel = 1; while (sourceImage.Width > 1 && sourceImage.Height > 1) { GL.TexSubImage2D(TextureTarget.Texture2D, mipLevel++, 0, 0, tempImage.Width, tempImage.Height, PixelFormat.Bgra, PixelType.UnsignedByte, tempImage.GetBuffer()); sourceImage = new ImageBuffer(tempImage); tempImage = new ImageBuffer(Math.Max(1, sourceImage.Width / 2), Math.Max(1, sourceImage.Height / 2), 32, new BlenderBGRA()); tempImage.NewGraphics2D().Render(sourceImage, 0, 0, 0, (double)tempImage.Width / (double)sourceImage.Width, (double)tempImage.Height / (double)sourceImage.Height); } } break; default: throw new NotImplementedException(); } } else { GL.GenerateMipmap(GenerateMipmapTarget.Texture2D); } } } #endif return plugin; }
public static ImageGlPlugin GetImageGlPlugin(ImageBuffer imageToGetDisplayListFor, bool createAndUseMipMaps, bool textureMagFilterLinear = true, bool clamp = true) { imagesWithCacheData.TryGetValue(imageToGetDisplayListFor.GetBuffer(), out ImageGlPlugin plugin); lock (glDataNeedingToBeDeleted) { // We run this in here to ensure that we are on the correct thread and have the correct // glcontext realized. for (int i = glDataNeedingToBeDeleted.Count - 1; i >= 0; i--) { int textureToDelete = glDataNeedingToBeDeleted[i].glTextureHandle; if (textureToDelete != -1 && glDataNeedingToBeDeleted[i].glContextId == contextId && glDataNeedingToBeDeleted[i].refreshCountCreatedOn == currentGlobalRefreshCount) // this is to leak on purpose on android for some gl that kills textures { GL.DeleteTextures(1, ref textureToDelete); if (removeGlDataCallBackHolder != null) { removeGlDataCallBackHolder.releaseAllGlData -= glDataNeedingToBeDeleted[i].DeleteTextureData; } } glDataNeedingToBeDeleted.RemoveAt(i); } } if (plugin != null && (imageToGetDisplayListFor.ChangedCount != plugin.imageUpdateCount || plugin.glData.refreshCountCreatedOn != currentGlobalRefreshCount || plugin.glData.glTextureHandle == -1)) { int textureToDelete = plugin.GLTextureHandle; if (plugin.glData.refreshCountCreatedOn == currentGlobalRefreshCount) { GL.DeleteTextures(1, ref textureToDelete); } plugin.glData.glTextureHandle = -1; imagesWithCacheData.Remove(imageToGetDisplayListFor.GetBuffer()); // use the original settings createAndUseMipMaps = plugin.createdWithMipMaps; clamp = plugin.clamp; plugin = null; } if (plugin == null) { var newPlugin = new ImageGlPlugin(); imagesWithCacheData.Add(imageToGetDisplayListFor.GetBuffer(), newPlugin); newPlugin.createdWithMipMaps = createAndUseMipMaps; newPlugin.clamp = clamp; newPlugin.glData.glContextId = contextId; newPlugin.CreateGlDataForImage(imageToGetDisplayListFor, textureMagFilterLinear); newPlugin.imageUpdateCount = imageToGetDisplayListFor.ChangedCount; newPlugin.glData.refreshCountCreatedOn = currentGlobalRefreshCount; if (removeGlDataCallBackHolder != null) { removeGlDataCallBackHolder.releaseAllGlData += newPlugin.glData.DeleteTextureData; } return(newPlugin); } return(plugin); }
static public ImageGlPlugin GetImageGlPlugin(ImageBuffer imageToGetDisplayListFor, bool createAndUseMipMaps, bool TextureMagFilterLinear = true) { ImageGlPlugin plugin; imagesWithCacheData.TryGetValue(imageToGetDisplayListFor.GetBuffer(), out plugin); using (TimedLock.Lock(glDataNeedingToBeDeleted, "GetImageGlPlugin")) { // We run this in here to ensure that we are on the correct thread and have the correct // glcontext realized. for (int i = glDataNeedingToBeDeleted.Count - 1; i >= 0; i--) { int textureToDelete = glDataNeedingToBeDeleted[i].glTextureHandle; if (glDataNeedingToBeDeleted[i].refreshCountCreatedOn == currentGlobalRefreshCount) { GL.DeleteTextures(1, ref textureToDelete); } glDataNeedingToBeDeleted.RemoveAt(i); } } #if ON_IMAGE_CHANGED_ALWAYS_CREATE_IMAGE if (plugin != null && (imageToGetDisplayListFor.ChangedCount != plugin.imageUpdateCount || plugin.glData.refreshCountCreatedOn != currentGlobalRefreshCount)) { int textureToDelete = plugin.GLTextureHandle; if (plugin.glData.refreshCountCreatedOn == currentGlobalRefreshCount) { GL.DeleteTextures(1, ref textureToDelete); } plugin.glData.glTextureHandle = 0; imagesWithCacheData.Remove(imageToGetDisplayListFor.GetBuffer()); plugin = null; } if (plugin == null) { ImageGlPlugin newPlugin = new ImageGlPlugin(); imagesWithCacheData.Add(imageToGetDisplayListFor.GetBuffer(), newPlugin); newPlugin.createdWithMipMaps = createAndUseMipMaps; newPlugin.CreateGlDataForImage(imageToGetDisplayListFor, TextureMagFilterLinear); newPlugin.imageUpdateCount = imageToGetDisplayListFor.ChangedCount; newPlugin.glData.refreshCountCreatedOn = currentGlobalRefreshCount; return(newPlugin); } #else if (plugin == null) { ImageGlPlugin newPlugin = new ImageGlPlugin(); imagesWithCacheData.Add(imageToGetDisplayListFor.GetBuffer(), newPlugin); newPlugin.createdWithMipMaps = createAndUseMipMaps; newPlugin.CreateGlDataForImage(imageToGetDisplayListFor, TextureMagFilterLinear); newPlugin.imageUpdateCount = imageToGetDisplayListFor.ChangedCount; newPlugin.refreshCountCreatedOn = currentGlobalRefreshCount; return(newPlugin); } if (imageToGetDisplayListFor.ChangedCount != plugin.imageUpdateCount || plugin.refreshCountCreatedOn != currentGlobalRefreshCount) { plugin.imageUpdateCount = imageToGetDisplayListFor.ChangedCount; plugin.refreshCountCreatedOn = currentGlobalRefreshCount; GL.BindTexture(TextureTarget.Texture2D, plugin.GLTextureHandle); // Create the texture switch (imageToGetDisplayListFor.BitDepth) { case 8: GL.TexSubImage2D(TextureTarget.Texture2D, 0, 0, 0, imageToGetDisplayListFor.Width, imageToGetDisplayListFor.Height, PixelFormat.Luminance, PixelType.UnsignedByte, imageToGetDisplayListFor.GetBuffer()); break; case 24: // our bitmaps are not padded and GL is having a problem with them so don't use 24 bit unless you fix this. GL.TexSubImage2D(TextureTarget.Texture2D, 0, 0, 0, imageToGetDisplayListFor.Width, imageToGetDisplayListFor.Height, PixelFormat.Bgr, PixelType.UnsignedByte, imageToGetDisplayListFor.GetBuffer()); break; case 32: GL.TexSubImage2D(TextureTarget.Texture2D, 0, 0, 0, imageToGetDisplayListFor.Width, imageToGetDisplayListFor.Height, PixelFormat.Bgra, PixelType.UnsignedByte, imageToGetDisplayListFor.GetBuffer()); break; default: throw new NotImplementedException(); } if (plugin.createdWithMipMaps) { if (GLMajorVersion < 3) { switch (imageToGetDisplayListFor.BitDepth) { case 32: { ImageBuffer sourceImage = new ImageBuffer(imageToGetDisplayListFor); ImageBuffer tempImage = new ImageBuffer(sourceImage.Width / 2, sourceImage.Height / 2, 32, new BlenderBGRA()); tempImage.NewGraphics2D().Render(sourceImage, 0, 0, 0, .5, .5); int mipLevel = 1; while (sourceImage.Width > 1 && sourceImage.Height > 1) { GL.TexSubImage2D(TextureTarget.Texture2D, mipLevel++, 0, 0, tempImage.Width, tempImage.Height, PixelFormat.Bgra, PixelType.UnsignedByte, tempImage.GetBuffer()); sourceImage = new ImageBuffer(tempImage); tempImage = new ImageBuffer(Math.Max(1, sourceImage.Width / 2), Math.Max(1, sourceImage.Height / 2), 32, new BlenderBGRA()); tempImage.NewGraphics2D().Render(sourceImage, 0, 0, 0, (double)tempImage.Width / (double)sourceImage.Width, (double)tempImage.Height / (double)sourceImage.Height); } } break; default: throw new NotImplementedException(); } } else { GL.GenerateMipmap(GenerateMipmapTarget.Texture2D); } } } #endif return(plugin); }