public GlSkiaGpu(IPlatformOpenGlInterface openGl, long?maxResourceBytes) { var context = openGl.PrimaryContext; _glContext = context; using (context.MakeCurrent()) { using (var iface = context.Version.Type == GlProfileType.OpenGL ? GRGlInterface.CreateOpenGl(proc => context.GlInterface.GetProcAddress(proc)) : GRGlInterface.CreateGles(proc => context.GlInterface.GetProcAddress(proc))) { _grContext = GRContext.CreateGl(iface, new GRContextOptions { AvoidStencilBuffers = true }); if (maxResourceBytes.HasValue) { _grContext.SetResourceCacheLimit(maxResourceBytes.Value); } } } }
private void DrawGpuTextureWithOldDesc(Action <SKSurface, GRBackendTextureDesc> draw) { using (var ctx = CreateGlContext()) { ctx.MakeCurrent(); // create the texture var textureInfo = ctx.CreateTexture(new SKSizeI(100, 100)); var oldInfo = new GRTextureInfoOld { Id = textureInfo.Id, Target = textureInfo.Target }; var textureHandle = GCHandle.Alloc(oldInfo, GCHandleType.Pinned); var textureDesc = new GRBackendTextureDesc { Width = 100, Height = 100, Config = GRPixelConfig.Rgba8888, Flags = GRBackendTextureDescFlags.RenderTarget, Origin = GRSurfaceOrigin.BottomLeft, SampleCount = 0, TextureHandle = textureHandle.AddrOfPinnedObject(), }; // create the surface using (var grContext = GRContext.CreateGl()) using (var surface = SKSurface.CreateAsRenderTarget(grContext, textureDesc)) { Assert.NotNull(surface); draw(surface, textureDesc); } // clean up textureHandle.Free(); ctx.DestroyTexture(textureInfo.Id); } }
protected override void OnRenderFrame() { // create the contexts if not done already if (grContext == null) { var glInterface = GRGlInterface.Create(); grContext = GRContext.CreateGl(glInterface); } // manage the drawing surface var alloc = Allocation; var res = (int)Math.Max(1.0, Gdk.Screen.Default.Resolution / 96.0); var w = Math.Max(0, alloc.Width * res); var h = Math.Max(0, alloc.Height * res); if (renderTarget == null || surface == null || renderTarget.Width != w || renderTarget.Height != h) { // create or update the dimensions renderTarget?.Dispose(); GL.GetInteger(GetPName.FramebufferBinding, out var framebuffer); GL.GetInteger(GetPName.StencilBits, out var stencil); GL.GetInteger(GetPName.Samples, out var samples); var maxSamples = grContext.GetMaxSurfaceSampleCount(COLOR_TYPE); if (samples > maxSamples) { samples = maxSamples; } var glInfo = new GRGlFramebufferInfo((uint)framebuffer, COLOR_TYPE.ToGlSizedFormat()); renderTarget = new GRBackendRenderTarget(w, h, samples, stencil, glInfo); // create the surface surface?.Dispose(); surface = SKSurface.Create(grContext, renderTarget, SURFACE_ORIGIN, COLOR_TYPE); } using (new SKAutoCanvasRestore(surface.Canvas, true)) { RenderFrame?.Invoke(this, surface); } // update the control surface.Canvas.Flush(); grContext.Flush(); }
public void CanvasCanRestoreOnGpu() { using (var ctx = CreateGlContext()) { ctx.MakeCurrent(); using (var grContext = GRContext.CreateGl()) using (var surface = SKSurface.Create(grContext, true, new SKImageInfo(100, 100))) { var canvas = surface.Canvas; Assert.Equal(SKMatrix.Identity, canvas.TotalMatrix); using (new SKAutoCanvasRestore(canvas)) { canvas.Translate(10, 10); Assert.Equal(SKMatrix.CreateTranslation(10, 10), canvas.TotalMatrix); } Assert.Equal(SKMatrix.Identity, canvas.TotalMatrix); } } }
private void DrawGpuTexture(Action <SKSurface, GRBackendTexture> draw) { using (var ctx = CreateGlContext()) { ctx.MakeCurrent(); // create the texture var textureInfo = ctx.CreateTexture(new SKSizeI(100, 100)); var texture = new GRBackendTexture(100, 100, false, textureInfo); // create the surface using (var grContext = GRContext.CreateGl()) using (var surface = SKSurface.CreateAsRenderTarget(grContext, texture, SKColorType.Rgba8888)) { Assert.NotNull(surface); draw(surface, texture); } // clean up ctx.DestroyTexture(textureInfo.Id); } }
protected void TkRender(TimeSpan delta) { if (designMode || disposed) { return; } if (this.Visibility != Visibility.Visible) { return; } var size = CreateSize(); if (size.Width <= 0 || size.Height <= 0) { return; } // create the contexts if not done already if (grContext == null) { var glInterface = GRGlInterface.Create(); grContext = GRContext.CreateGl(glInterface); } // get the new surface size var newSize = new SKSizeI(size.Width, size.Height); // manage the drawing surface if (renderTarget == null || lastSize != newSize || !renderTarget.IsValid) { // create or update the dimensions lastSize = newSize; GL.GetInteger(GetPName.FramebufferBinding, out var framebuffer); GL.GetInteger(GetPName.StencilBits, out var stencil); GL.GetInteger(GetPName.Samples, out var samples); var maxSamples = grContext.GetMaxSurfaceSampleCount(colorType); if (samples > maxSamples) { samples = maxSamples; } glInfo = new GRGlFramebufferInfo((uint)framebuffer, colorType.ToGlSizedFormat()); // destroy the old surface surface?.Dispose(); surface = null; canvas = null; // re-create the render target renderTarget?.Dispose(); renderTarget = new GRBackendRenderTarget(newSize.Width, newSize.Height, samples, stencil, glInfo); } // create the surface if (surface == null) { surface = SKSurface.Create(grContext, renderTarget, surfaceOrigin, colorType); canvas = surface.Canvas; } using (new SKAutoCanvasRestore(canvas, true)) { // start drawing OnPaintSurface(new SKPaintGLSurfaceEventArgs(surface, renderTarget, surfaceOrigin, colorType, glInfo)); } // update the control canvas.Flush(); }
private void UnoGLDrawingArea_Render(object o, RenderArgs args) { args.Context.MakeCurrent(); // create the contexts if not done already if (_grContext == null) { var glInterface = GRGlInterface.Create(); _grContext = GRContext.CreateGl(glInterface); } // manage the drawing surface var res = (int)Math.Max(1.0, Screen.Resolution / 96.0); var w = Math.Max(0, AllocatedWidth * res); var h = Math.Max(0, AllocatedHeight * res); if (_renderTarget == null || _surface == null || _renderTarget.Width != w || _renderTarget.Height != h) { // create or update the dimensions _renderTarget?.Dispose(); _gl.GetInteger(GLEnum.FramebufferBinding, out var framebuffer); _gl.GetInteger(GLEnum.Stencil, out var stencil); _gl.GetInteger(GLEnum.Samples, out var samples); var maxSamples = _grContext.GetMaxSurfaceSampleCount(colorType); if (samples > maxSamples) { samples = maxSamples; } var glInfo = new GRGlFramebufferInfo((uint)framebuffer, colorType.ToGlSizedFormat()); _renderTarget = new GRBackendRenderTarget(w + GuardBand, h + GuardBand, samples, stencil, glInfo); // create the surface _surface?.Dispose(); _surface = SKSurface.Create(_grContext, _renderTarget, surfaceOrigin, colorType); if (this.Log().IsEnabled(LogLevel.Trace)) { this.Log().Trace($"Recreate render surface {w}x{h} colorType:{colorType} sample:{samples}"); } } _gl.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.StencilBufferBit | ClearBufferMask.DepthBufferBit); _gl.ClearColor(1.0f, 1.0f, 1.0f, 1.0f); var canvas = _surface.Canvas; using (new SKAutoCanvasRestore(canvas, true)) { canvas.Clear(SKColors.White); canvas.Translate(new SKPoint(0, GuardBand)); WUX.Window.Current.Compositor.Render(_surface); } // update the control canvas.Flush(); _gl.Flush(); }
public void ImageCanClearBackground(float threshold, float exponent, uint backgroundColor, uint shirtColor) { using var ctx = CreateGlContext(); ctx.MakeCurrent(); using var grContext = GRContext.CreateGl(); var info = new SKImageInfo(500, 500, SKColorType.Rgba8888); using var surface = SKSurface.Create(grContext, false, info); var canvas = surface.Canvas; canvas.Clear(SKColors.Black); using var blueShirt = SKImage.FromEncodedData(Path.Combine(PathToImages, "blue-shirt.jpg")); using var textureShader = blueShirt.ToShader(); var src = @" uniform shader color_map; uniform float scale; uniform half exp; uniform float3 in_colors0; half4 main(float2 p) { half4 texColor = sample(color_map, p); if (length(abs(in_colors0 - pow(texColor.rgb, half3(exp)))) < scale) discard; return texColor; }"; using var effect = SKRuntimeEffect.Create(src, out var errorText); Assert.Null(errorText); Assert.NotNull(effect); var uniformSize = effect.UniformSize; Assert.Equal(5 * sizeof(float), uniformSize); var uniforms = new SKRuntimeEffectUniforms(effect) { ["scale"] = threshold, ["exp"] = exponent, ["in_colors0"] = new[] { 1f, 1f, 1f }, }; var children = new SKRuntimeEffectChildren(effect) { ["color_map"] = textureShader }; using var shader = effect.ToShader(true, uniforms, children); using var paint = new SKPaint { Shader = shader }; canvas.DrawRect(SKRect.Create(400, 400), paint); var actual = new SKColor[500 * 500]; fixed(void *a = actual) Assert.True(surface.ReadPixels(info, (IntPtr)a, info.RowBytes, 0, 0)); Assert.Equal(backgroundColor, actual[100 * info.Width + 100]); Assert.Equal(shirtColor, actual[230 * info.Width + 300]); }
public new void DrawInRect(GLKView view, CGRect rect) { if (designMode) { return; } // create the contexts if not done already if (context == null) { var glInterface = GRGlInterface.Create(); context = GRContext.CreateGl(glInterface); } // get the new surface size var newSize = new SKSizeI((int)DrawableWidth, (int)DrawableHeight); // manage the drawing surface if (renderTarget == null || lastSize != newSize || !renderTarget.IsValid) { // create or update the dimensions lastSize = newSize; // read the info from the buffer Gles.glGetIntegerv(Gles.GL_FRAMEBUFFER_BINDING, out var framebuffer); Gles.glGetIntegerv(Gles.GL_STENCIL_BITS, out var stencil); Gles.glGetIntegerv(Gles.GL_SAMPLES, out var samples); var maxSamples = context.GetMaxSurfaceSampleCount(colorType); if (samples > maxSamples) { samples = maxSamples; } glInfo = new GRGlFramebufferInfo((uint)framebuffer, colorType.ToGlSizedFormat()); // destroy the old surface surface?.Dispose(); surface = null; canvas = null; // re-create the render target renderTarget?.Dispose(); renderTarget = new GRBackendRenderTarget(newSize.Width, newSize.Height, samples, stencil, glInfo); } // create the surface if (surface == null) { surface = SKSurface.Create(context, renderTarget, surfaceOrigin, colorType); canvas = surface.Canvas; } using (new SKAutoCanvasRestore(canvas, true)) { // start drawing var e = new SKPaintGLSurfaceEventArgs(surface, renderTarget, surfaceOrigin, colorType, glInfo); OnPaintSurface(e); #pragma warning disable CS0618 // Type or member is obsolete DrawInSurface(e.Surface, e.RenderTarget); #pragma warning restore CS0618 // Type or member is obsolete } // flush the SkiaSharp contents to GL canvas.Flush(); context.Flush(); }