Moved a few types around and tweaked the APIs a bit to match the others
This commit is contained in:
Родитель
9d4f672584
Коммит
1d7290a627
|
@ -5,6 +5,7 @@ using SKFormsView = SkiaSharp.Views.Forms.SKCanvasView;
|
|||
using SKNativeView = SkiaSharp.Views.Tizen.SKCanvasView;
|
||||
|
||||
[assembly: ExportRenderer(typeof(SKFormsView), typeof(SkiaSharp.Views.Forms.SKCanvasViewRenderer))]
|
||||
|
||||
namespace SkiaSharp.Views.Forms
|
||||
{
|
||||
public class SKCanvasViewRenderer : SKCanvasViewRendererBase<SKFormsView, SKNativeView>, IRegisterable
|
||||
|
|
|
@ -5,6 +5,7 @@ using SKFormsView = SkiaSharp.Views.Forms.SKGLView;
|
|||
using SKNativeView = SkiaSharp.Views.Tizen.SKGLSurfaceView;
|
||||
|
||||
[assembly: ExportRenderer(typeof(SKFormsView), typeof(SkiaSharp.Views.Forms.SKGLViewRenderer))]
|
||||
|
||||
namespace SkiaSharp.Views.Forms
|
||||
{
|
||||
public class SKGLViewRenderer : SKGLViewRendererBase<SKFormsView, SKNativeView>
|
||||
|
|
|
@ -1,14 +1,15 @@
|
|||
using SkiaSharp.Views.Tizen;
|
||||
using System.IO;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Platform.Tizen;
|
||||
|
||||
[assembly: ExportImageSourceHandler(typeof(SkiaSharp.Views.Forms.SKImageImageSource), typeof(SkiaSharp.Views.Forms.SKImageImageSourceHandler))]
|
||||
[assembly: ExportImageSourceHandler(typeof(SkiaSharp.Views.Forms.SKBitmapImageSource), typeof(SkiaSharp.Views.Forms.SKBitmapImageSourceeHandler))]
|
||||
[assembly: ExportImageSourceHandler(typeof(SkiaSharp.Views.Forms.SKPixmapImageSource), typeof(SkiaSharp.Views.Forms.SKPixmapImageSourceHandler))]
|
||||
[assembly: ExportImageSourceHandler(typeof(SkiaSharp.Views.Forms.SKPictureImageSource), typeof(SkiaSharp.Views.Forms.SKPictureImageSourceHandler))]
|
||||
using NativeImage = Xamarin.Forms.Platform.Tizen.Native.Image;
|
||||
|
||||
[assembly: ExportImageSourceHandler(typeof(SkiaSharp.Views.Forms.SKImageImageSource), typeof(SkiaSharp.Views.Forms.SKImageSourceHandler))]
|
||||
[assembly: ExportImageSourceHandler(typeof(SkiaSharp.Views.Forms.SKBitmapImageSource), typeof(SkiaSharp.Views.Forms.SKImageSourceHandler))]
|
||||
[assembly: ExportImageSourceHandler(typeof(SkiaSharp.Views.Forms.SKPixmapImageSource), typeof(SkiaSharp.Views.Forms.SKImageSourceHandler))]
|
||||
[assembly: ExportImageSourceHandler(typeof(SkiaSharp.Views.Forms.SKPictureImageSource), typeof(SkiaSharp.Views.Forms.SKImageSourceHandler))]
|
||||
|
||||
namespace SkiaSharp.Views.Forms
|
||||
{
|
||||
|
@ -16,52 +17,32 @@ namespace SkiaSharp.Views.Forms
|
|||
{
|
||||
private StreamImageSourceHandler handler = new StreamImageSourceHandler();
|
||||
|
||||
public Task<bool> LoadImageAsync(Xamarin.Forms.Platform.Tizen.Native.Image image, ImageSource imageSource, CancellationToken cancelationToken = default(CancellationToken))
|
||||
public Task<bool> LoadImageAsync(NativeImage image, ImageSource imageSource, CancellationToken cancelationToken = default(CancellationToken))
|
||||
{
|
||||
return handler.LoadImageAsync(image, ImageSource.FromStream(() => ToStream(imageSource)), cancelationToken);
|
||||
}
|
||||
ImageSource newSource = null;
|
||||
|
||||
protected abstract Stream ToStream(ImageSource imageSource);
|
||||
}
|
||||
|
||||
public sealed class SKImageImageSourceHandler : SKImageSourceHandler
|
||||
{
|
||||
protected override Stream ToStream(ImageSource imageSource)
|
||||
{
|
||||
return (imageSource as SKImageImageSource)?.Image?.ToStream();
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class SKBitmapImageSourceeHandler : SKImageSourceHandler
|
||||
{
|
||||
protected override Stream ToStream(ImageSource imageSource)
|
||||
{
|
||||
return (imageSource as SKBitmapImageSource)?.Bitmap?.ToStream();
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class SKPixmapImageSourceHandler : SKImageSourceHandler
|
||||
{
|
||||
protected override Stream ToStream(ImageSource imageSource)
|
||||
{
|
||||
return (imageSource as SKPixmapImageSource)?.Pixmap?.ToStream();
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class SKPictureImageSourceHandler : SKImageSourceHandler
|
||||
{
|
||||
protected override Stream ToStream(ImageSource imageSource)
|
||||
{
|
||||
var pictureImageSource = imageSource as SKPictureImageSource;
|
||||
|
||||
if (pictureImageSource != null)
|
||||
switch (imageSource)
|
||||
{
|
||||
return pictureImageSource.Picture?.ToStream(pictureImageSource.Dimensions);
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
case SKImageImageSource imageImageSource:
|
||||
newSource = ImageSource.FromStream(() => ToStream(imageImageSource.Image));
|
||||
break;
|
||||
case SKBitmapImageSource bitmapImageSource:
|
||||
newSource = ImageSource.FromStream(() => ToStream(SKImage.FromBitmap(bitmapImageSource.Bitmap)));
|
||||
break;
|
||||
case SKPixmapImageSource pixmapImageSource:
|
||||
newSource = ImageSource.FromStream(() => ToStream(SKImage.FromPixels(pixmapImageSource.Pixmap)));
|
||||
break;
|
||||
case SKPictureImageSource pictureImageSource:
|
||||
newSource = ImageSource.FromStream(() => ToStream(SKImage.FromPicture(pictureImageSource.Picture, pictureImageSource.Dimensions)));
|
||||
break;
|
||||
}
|
||||
|
||||
return handler.LoadImageAsync(image, newSource, cancelationToken);
|
||||
}
|
||||
|
||||
private static Stream ToStream(SKImage skiaImage)
|
||||
{
|
||||
return skiaImage.Encode().AsStream();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,11 +6,8 @@ namespace SkiaSharp.Views.Forms
|
|||
internal class SKTouchHandler
|
||||
{
|
||||
private readonly MomentumHandler momentumHandler;
|
||||
|
||||
private Action<SKTouchEventArgs> onTouchAction;
|
||||
|
||||
private Func<float, float> scalePixels;
|
||||
|
||||
private GestureLayer gestureLayer;
|
||||
|
||||
public SKTouchHandler(Action<SKTouchEventArgs> onTouchAction, Func<float, float> scalePixels)
|
||||
|
@ -26,13 +23,9 @@ namespace SkiaSharp.Views.Forms
|
|||
if (view != null)
|
||||
{
|
||||
if (enableTouchEvents)
|
||||
{
|
||||
CreateGestureLayer(view);
|
||||
}
|
||||
else
|
||||
{
|
||||
DestroyGestureLayer();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -84,7 +77,6 @@ namespace SkiaSharp.Views.Forms
|
|||
private class MomentumHandler
|
||||
{
|
||||
private readonly SKTouchHandler handler;
|
||||
|
||||
private int currentId = 0;
|
||||
|
||||
public MomentumHandler(SKTouchHandler h)
|
||||
|
@ -116,9 +108,7 @@ namespace SkiaSharp.Views.Forms
|
|||
private void PostEvent(SKTouchAction action)
|
||||
{
|
||||
if (handler.onTouchAction == null || handler.scalePixels == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var p = handler.gestureLayer.EvasCanvas.Pointer;
|
||||
var coords = new SKPoint(handler.scalePixels(p.X), handler.scalePixels(p.Y));
|
||||
|
|
|
@ -1,54 +1,30 @@
|
|||
using ElmSharp;
|
||||
using System;
|
||||
using System;
|
||||
using ElmSharp;
|
||||
using SkiaSharp.Views.Tizen.Interop;
|
||||
|
||||
namespace SkiaSharp.Views.Tizen
|
||||
{
|
||||
/// <summary>
|
||||
/// Widget which allows to implement custom rendering procedure.
|
||||
/// </summary>
|
||||
/// kkk
|
||||
public abstract class CustomRenderingView : Widget
|
||||
public abstract class CustomRenderingView : Widget
|
||||
{
|
||||
// called when image needs to be redrawn
|
||||
private readonly Interop.Evas.Image.ImagePixelsSetCallback redrawCallback;
|
||||
private readonly Evas.ImagePixelsSetCallback redrawCallback;
|
||||
|
||||
// used to redraw the surface at every animation tick (when render mode is set to RenderingMode.Continuously)
|
||||
private IntPtr animator;
|
||||
|
||||
// type of rendering
|
||||
private RenderingMode renderingMode = RenderingMode.WhenDirty;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance with the given object as its parent.
|
||||
/// </summary>
|
||||
/// <param name="parent">The parent object.</param>
|
||||
public CustomRenderingView(EvasObject parent) : base(parent)
|
||||
protected IntPtr evasImage;
|
||||
|
||||
public CustomRenderingView(EvasObject parent)
|
||||
: base(parent)
|
||||
{
|
||||
// initialize the callbacks
|
||||
Resized += (sender, e) => OnResized();
|
||||
redrawCallback = (d, o) => OnDrawFrame();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The size of the surface.
|
||||
/// </summary>
|
||||
public SKSize SurfaceSize => new SKSize(SurfaceWidth, SurfaceHeight);
|
||||
public SKSize CanvasSize => GetSurfaceSize();
|
||||
|
||||
public SKSize CanvasSize => SurfaceSize;
|
||||
|
||||
/// <summary>
|
||||
/// Rendering mode used to control repainting the surface.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Default value is RenderingMode.WhenDirty.
|
||||
/// </remarks>
|
||||
public RenderingMode RenderingMode
|
||||
{
|
||||
get
|
||||
{
|
||||
return renderingMode;
|
||||
}
|
||||
|
||||
get { return renderingMode; }
|
||||
set
|
||||
{
|
||||
if (renderingMode != value)
|
||||
|
@ -56,137 +32,62 @@ namespace SkiaSharp.Views.Tizen
|
|||
renderingMode = value;
|
||||
|
||||
if (renderingMode == RenderingMode.Continuously)
|
||||
{
|
||||
CreateAnimator();
|
||||
}
|
||||
else
|
||||
{
|
||||
DestroyAnimator();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Width of the drawing surface.
|
||||
/// </summary>
|
||||
protected abstract int SurfaceWidth
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Height of the drawing surface.
|
||||
/// </summary>
|
||||
protected abstract int SurfaceHeight
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Displays the rendered content.
|
||||
/// </summary>
|
||||
protected IntPtr EvasImage
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Requests to repaint the surface.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Surface is repainted when RenderingMode is set to RenderingMode.WhenDirty, otherwise repainting is controlled by EFL.
|
||||
/// </remarks>
|
||||
public void Invalidate()
|
||||
{
|
||||
if (RenderingMode == RenderingMode.WhenDirty)
|
||||
{
|
||||
Repaint();
|
||||
}
|
||||
Evas.evas_object_image_pixels_dirty_set(evasImage, true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates the native resources which should be present throughout whole life of the control.
|
||||
/// </summary>
|
||||
/// <param name="parent">The parent object.</param>
|
||||
/// <remarks>
|
||||
/// This method is empty.
|
||||
/// </remarks>
|
||||
protected virtual void CreateNativeResources(EvasObject parent)
|
||||
{
|
||||
// empty on purpose
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Destroys the native resources.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This method is empty.
|
||||
/// </remarks>
|
||||
protected virtual void DestroyNativeResources()
|
||||
{
|
||||
// empty on purpose
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Current frame should be drawn into the image.
|
||||
/// </summary>
|
||||
protected abstract void OnDrawFrame();
|
||||
|
||||
/// <summary>
|
||||
/// Updates the drawing surface's size.
|
||||
/// </summary>
|
||||
/// <param name="geometry">Current geometry of the control.</param>
|
||||
/// <returns>true, if size has changed, false otherwise.</returns>
|
||||
protected abstract bool UpdateSurfaceSize(Rect geometry);
|
||||
|
||||
/// <summary>
|
||||
/// Creates the drawing surface.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This method is empty.
|
||||
/// </remarks>
|
||||
protected abstract SKSizeI GetSurfaceSize();
|
||||
|
||||
protected virtual void CreateDrawingSurface()
|
||||
{
|
||||
// empty on purpose
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Destroys the drawing surface.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This method is empty.
|
||||
/// </remarks>
|
||||
protected virtual void DestroyDrawingSurface()
|
||||
{
|
||||
// empty on purpose
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates the EFL controls.
|
||||
/// </summary>
|
||||
/// <param name="parent">The parent object.</param>
|
||||
/// <returns>Pointer to the newly created control.</returns>
|
||||
protected sealed override IntPtr CreateHandle(EvasObject parent)
|
||||
{
|
||||
IntPtr handle = Interop.Elementary.elm_layout_add(parent);
|
||||
var handle = Interop.Elementary.elm_layout_add(parent);
|
||||
Interop.Elementary.elm_layout_theme_set(handle, "layout", "background", "default");
|
||||
|
||||
EvasImage = Interop.Evas.Image.evas_object_image_filled_add(Interop.Evas.evas_object_evas_get(handle));
|
||||
Interop.Evas.Image.evas_object_image_colorspace_set(EvasImage, Interop.Evas.Image.Colorspace.ARGB8888);
|
||||
Interop.Evas.Image.evas_object_image_smooth_scale_set(EvasImage, true);
|
||||
Interop.Evas.Image.evas_object_image_alpha_set(EvasImage, true);
|
||||
evasImage = Evas.evas_object_image_filled_add(Interop.Evas.evas_object_evas_get(handle));
|
||||
Evas.evas_object_image_colorspace_set(evasImage, Evas.Colorspace.ARGB8888);
|
||||
Evas.evas_object_image_smooth_scale_set(evasImage, true);
|
||||
Evas.evas_object_image_alpha_set(evasImage, true);
|
||||
|
||||
Interop.Elementary.elm_object_part_content_set(handle, "elm.swallow.content", EvasImage);
|
||||
Interop.Elementary.elm_object_part_content_set(handle, "elm.swallow.content", evasImage);
|
||||
|
||||
CreateNativeResources(parent);
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Cleans up.
|
||||
/// </summary>
|
||||
protected sealed override void OnUnrealize()
|
||||
{
|
||||
DestroyAnimator();
|
||||
|
@ -196,59 +97,42 @@ namespace SkiaSharp.Views.Tizen
|
|||
base.OnUnrealize();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Notifies that the size of the drawing surface has changed.
|
||||
/// </summary>
|
||||
protected void OnSurfaceSizeChanged()
|
||||
{
|
||||
OnResized();
|
||||
}
|
||||
|
||||
private void OnResized()
|
||||
protected void OnResized()
|
||||
{
|
||||
var geometry = Geometry;
|
||||
|
||||
// control is not yet fully initialized
|
||||
if (geometry.Width <= 0 || geometry.Height <= 0)
|
||||
{
|
||||
// control is not yet fully initialized
|
||||
return;
|
||||
}
|
||||
|
||||
if (UpdateSurfaceSize(geometry))
|
||||
{
|
||||
RemoveImageCallback();
|
||||
// disconnect the callback
|
||||
Evas.evas_object_image_native_surface_set(evasImage, IntPtr.Zero);
|
||||
|
||||
// recreate the drawing surface to match the new size
|
||||
DestroyDrawingSurface();
|
||||
ResizeImage();
|
||||
|
||||
var size = GetSurfaceSize();
|
||||
Evas.evas_object_image_size_set(evasImage, size.Width, size.Height);
|
||||
|
||||
CreateDrawingSurface();
|
||||
|
||||
SetImageCallback();
|
||||
// set the image callback; will be invoked when image is marked as dirty
|
||||
Evas.evas_object_image_pixels_get_callback_set(evasImage, redrawCallback, IntPtr.Zero);
|
||||
|
||||
// repaint
|
||||
Invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
private void ResizeImage()
|
||||
{
|
||||
// resize the image buffers
|
||||
Interop.Evas.Image.evas_object_image_size_set(EvasImage, SurfaceWidth, SurfaceHeight);
|
||||
}
|
||||
|
||||
private void Repaint()
|
||||
{
|
||||
// mark the image as dirty
|
||||
Interop.Evas.Image.evas_object_image_pixels_dirty_set(EvasImage, true);
|
||||
}
|
||||
|
||||
private void CreateAnimator()
|
||||
{
|
||||
if (animator == IntPtr.Zero)
|
||||
{
|
||||
animator = EcoreAnimator.AddAnimator(() =>
|
||||
{
|
||||
Repaint();
|
||||
Evas.evas_object_image_pixels_dirty_set(evasImage, true);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
@ -262,17 +146,5 @@ namespace SkiaSharp.Views.Tizen
|
|||
animator = IntPtr.Zero;
|
||||
}
|
||||
}
|
||||
|
||||
private void SetImageCallback()
|
||||
{
|
||||
// set the image callback; will be invoked when image is marked as dirty
|
||||
Interop.Evas.Image.evas_object_image_pixels_get_callback_set(EvasImage, redrawCallback, IntPtr.Zero);
|
||||
}
|
||||
|
||||
private void RemoveImageCallback()
|
||||
{
|
||||
// disconnect the callback
|
||||
Interop.Evas.Image.evas_object_image_native_surface_set(EvasImage, IntPtr.Zero);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
internal static partial class Interop
|
||||
namespace SkiaSharp.Views.Tizen.Interop
|
||||
{
|
||||
internal static partial class Elementary
|
||||
internal static class Elementary
|
||||
{
|
||||
[DllImport(Libraries.Elementary)]
|
||||
internal static extern IntPtr elm_layout_add(IntPtr obj);
|
||||
|
@ -16,5 +16,8 @@ internal static partial class Interop
|
|||
|
||||
[DllImport(Libraries.Elementary)]
|
||||
internal static extern void elm_object_part_content_set(IntPtr obj, string part, IntPtr content);
|
||||
|
||||
[DllImport(Libraries.Elementary)]
|
||||
internal static extern IntPtr elm_image_object_get(IntPtr obj);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,195 @@
|
|||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace SkiaSharp.Views.Tizen.Interop
|
||||
{
|
||||
internal static class Evas
|
||||
{
|
||||
[DllImport(Libraries.Evas)]
|
||||
internal static extern IntPtr evas_object_evas_get(IntPtr obj);
|
||||
|
||||
[DllImport(Libraries.Evas)]
|
||||
internal static extern IntPtr evas_gl_new(IntPtr evas);
|
||||
|
||||
[DllImport(Libraries.Evas)]
|
||||
internal static extern void evas_gl_free(IntPtr evas_gl);
|
||||
|
||||
[DllImport(Libraries.Evas)]
|
||||
internal static extern IntPtr evas_gl_context_create(IntPtr evas_gl, IntPtr share_ctx);
|
||||
|
||||
[DllImport(Libraries.Evas)]
|
||||
internal static extern void evas_gl_context_destroy(IntPtr evas_gl, IntPtr ctx);
|
||||
|
||||
[DllImport(Libraries.Evas)]
|
||||
internal static extern IntPtr evas_gl_surface_create(IntPtr evas_gl, IntPtr config, int width, int height);
|
||||
|
||||
[DllImport(Libraries.Evas)]
|
||||
internal static extern void evas_gl_surface_destroy(IntPtr evas_gl, IntPtr surf);
|
||||
|
||||
[DllImport(Libraries.Evas)]
|
||||
[return: MarshalAs(UnmanagedType.U1)]
|
||||
internal static extern bool evas_gl_native_surface_get(IntPtr evas_gl, IntPtr surf, out NativeSurfaceOpenGL ns);
|
||||
|
||||
[DllImport(Libraries.Evas)]
|
||||
internal static extern IntPtr evas_gl_proc_address_get(IntPtr evas_gl, string name);
|
||||
|
||||
[DllImport(Libraries.Evas)]
|
||||
internal static extern IntPtr evas_gl_api_get(IntPtr evas_gl);
|
||||
|
||||
[DllImport(Libraries.Evas)]
|
||||
[return: MarshalAs(UnmanagedType.U1)]
|
||||
internal static extern bool evas_gl_make_current(IntPtr evas_gl, IntPtr surf, IntPtr ctx);
|
||||
|
||||
internal struct Config
|
||||
{
|
||||
public ColorFormat color_format;
|
||||
public DepthBits depth_bits;
|
||||
public StencilBits stencil_bits;
|
||||
public OptionsBits options_bits;
|
||||
public MultisampleBits multisample_bits;
|
||||
public ContextVersion gles_version;
|
||||
}
|
||||
|
||||
// This structure is used to move data from one entity into another.
|
||||
internal struct NativeSurfaceOpenGL
|
||||
{
|
||||
public uint texture_id;
|
||||
public uint framebuffer_id;
|
||||
public uint internal_format;
|
||||
public uint format;
|
||||
public uint x;
|
||||
public uint y;
|
||||
public uint w;
|
||||
public uint h;
|
||||
}
|
||||
|
||||
internal enum ColorFormat
|
||||
{
|
||||
RGB_888 = 0,
|
||||
RGBA_8888 = 1,
|
||||
NO_FBO = 2
|
||||
}
|
||||
|
||||
internal enum DepthBits
|
||||
{
|
||||
NONE = 0,
|
||||
BIT_8 = 1,
|
||||
BIT_16 = 2,
|
||||
BIT_24 = 3,
|
||||
BIT_32 = 4
|
||||
}
|
||||
|
||||
internal enum StencilBits
|
||||
{
|
||||
NONE = 0,
|
||||
BIT_1 = 1,
|
||||
BIT_2 = 2,
|
||||
BIT_4 = 3,
|
||||
BIT_8 = 4,
|
||||
BIT_16 = 5
|
||||
}
|
||||
|
||||
internal enum OptionsBits
|
||||
{
|
||||
NONE = 0,
|
||||
DIRECT = (1 << 0),
|
||||
CLIENT_SIDE_ROTATION = (1 << 1),
|
||||
THREAD = (1 << 2)
|
||||
}
|
||||
|
||||
internal enum MultisampleBits
|
||||
{
|
||||
NONE = 0,
|
||||
LOW = 1,
|
||||
MED = 2,
|
||||
HIGH = 3
|
||||
}
|
||||
|
||||
internal enum ContextVersion
|
||||
{
|
||||
GLES_1_X = 1,
|
||||
GLES_2_X = 2,
|
||||
GLES_3_X = 3,
|
||||
DEBUG = 0x1000
|
||||
}
|
||||
|
||||
[DllImport(Libraries.Evas)]
|
||||
internal static extern IntPtr evas_object_image_add(IntPtr obj);
|
||||
|
||||
[DllImport(Libraries.Evas)]
|
||||
internal static extern IntPtr evas_object_image_filled_add(IntPtr obj);
|
||||
|
||||
[DllImport(Libraries.Evas)]
|
||||
internal static extern void evas_object_image_size_get(IntPtr obj, IntPtr x, out int y);
|
||||
|
||||
[DllImport(Libraries.Evas)]
|
||||
internal static extern void evas_object_image_size_get(IntPtr obj, out int x, IntPtr y);
|
||||
|
||||
[DllImport(Libraries.Evas)]
|
||||
internal static extern void evas_object_image_size_get(IntPtr obj, out int x, out int y);
|
||||
|
||||
[DllImport(Libraries.Evas)]
|
||||
internal static extern void evas_object_image_size_set(IntPtr obj, int w, int h);
|
||||
|
||||
[DllImport(Libraries.Evas)]
|
||||
internal static extern IntPtr evas_object_image_data_get(IntPtr obj, bool for_writing);
|
||||
|
||||
[DllImport(Libraries.Evas)]
|
||||
internal static extern void evas_object_image_data_set(IntPtr obj, IntPtr data);
|
||||
|
||||
[DllImport(Libraries.Evas)]
|
||||
internal static extern void evas_object_image_data_update_add(IntPtr obj, int x, int y, int w, int h);
|
||||
|
||||
[DllImport(Libraries.Evas)]
|
||||
internal static extern void evas_object_image_colorspace_set(IntPtr obj, Colorspace cspace);
|
||||
|
||||
[DllImport(Libraries.Evas)]
|
||||
internal static extern void evas_object_image_fill_set(IntPtr obj, int x, int y, int w, int h);
|
||||
|
||||
[DllImport(Libraries.Evas)]
|
||||
internal static extern void evas_object_image_native_surface_set(IntPtr obj, ref NativeSurfaceOpenGL surf);
|
||||
|
||||
[DllImport(Libraries.Evas)]
|
||||
internal static extern void evas_object_image_native_surface_set(IntPtr obj, IntPtr zero);
|
||||
|
||||
[DllImport(Libraries.Evas)]
|
||||
internal static extern void evas_object_image_pixels_dirty_set(IntPtr obj, bool dirty);
|
||||
|
||||
[DllImport(Libraries.Evas)]
|
||||
internal static extern void evas_object_image_pixels_get_callback_set(IntPtr obj, ImagePixelsSetCallback func, IntPtr data);
|
||||
|
||||
[DllImport(Libraries.Evas)]
|
||||
internal static extern void evas_object_image_pixels_get_callback_set(IntPtr obj, IntPtr zero, IntPtr data);
|
||||
|
||||
[DllImport(Libraries.Evas)]
|
||||
internal static extern void evas_object_image_smooth_scale_set(IntPtr obj, bool smooth_scale);
|
||||
|
||||
[DllImport(Libraries.Evas)]
|
||||
internal static extern void evas_object_image_alpha_set(IntPtr obj, bool has_alpha);
|
||||
|
||||
public delegate void ImagePixelsSetCallback(IntPtr data, IntPtr o);
|
||||
|
||||
internal enum Colorspace
|
||||
{
|
||||
ARGB8888,
|
||||
YCBCR422P601_PL,
|
||||
YCBCR422P709_PL,
|
||||
RGB565_A5P,
|
||||
GRY8 = 4,
|
||||
YCBCR422601_PL,
|
||||
YCBCR420NV12601_PL,
|
||||
YCBCR420TM12601_PL,
|
||||
AGRY88 = 8,
|
||||
ETC1 = 9,
|
||||
RGB8_ETC2 = 10,
|
||||
RGBA8_ETC2_EAC = 11,
|
||||
ETC1_ALPHA = 12,
|
||||
RGB_S3TC_DXT1 = 13,
|
||||
RGBA_S3TC_DXT1 = 14,
|
||||
RGBA_S3TC_DXT2 = 15,
|
||||
RGBA_S3TC_DXT3 = 16,
|
||||
RGBA_S3TC_DXT4 = 17,
|
||||
RGBA_S3TC_DXT5 = 18,
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
internal static partial class Interop
|
||||
{
|
||||
internal static partial class Elementary
|
||||
{
|
||||
[DllImport(Libraries.Elementary)]
|
||||
internal static extern IntPtr elm_image_object_get(IntPtr obj);
|
||||
}
|
||||
}
|
|
@ -1,230 +0,0 @@
|
|||
using System;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
internal static partial class Interop
|
||||
{
|
||||
internal static partial class Evas
|
||||
{
|
||||
internal static partial class GL
|
||||
{
|
||||
[DllImport(Libraries.Evas)]
|
||||
internal static extern IntPtr evas_gl_new(IntPtr evas);
|
||||
|
||||
[DllImport(Libraries.Evas)]
|
||||
internal static extern void evas_gl_free(IntPtr evas_gl);
|
||||
|
||||
[DllImport(Libraries.Evas)]
|
||||
internal static extern IntPtr evas_gl_context_create(IntPtr evas_gl, IntPtr share_ctx);
|
||||
|
||||
[DllImport(Libraries.Evas)]
|
||||
internal static extern void evas_gl_context_destroy(IntPtr evas_gl, IntPtr ctx);
|
||||
|
||||
[DllImport(Libraries.Evas)]
|
||||
internal static extern IntPtr evas_gl_surface_create(IntPtr evas_gl, IntPtr config, int width, int height);
|
||||
|
||||
[DllImport(Libraries.Evas)]
|
||||
internal static extern void evas_gl_surface_destroy(IntPtr evas_gl, IntPtr surf);
|
||||
|
||||
[DllImport(Libraries.Evas)]
|
||||
[return: MarshalAs(UnmanagedType.U1)]
|
||||
internal static extern bool evas_gl_native_surface_get(IntPtr evas_gl, IntPtr surf, out NativeSurfaceOpenGL ns);
|
||||
|
||||
[DllImport(Libraries.Evas)]
|
||||
internal static extern IntPtr evas_gl_proc_address_get(IntPtr evas_gl, string name);
|
||||
|
||||
[DllImport(Libraries.Evas)]
|
||||
internal static extern IntPtr evas_gl_api_get(IntPtr evas_gl);
|
||||
|
||||
[DllImport(Libraries.Evas)]
|
||||
[return: MarshalAs(UnmanagedType.U1)]
|
||||
internal static extern bool evas_gl_make_current(IntPtr evas_gl, IntPtr surf, IntPtr ctx);
|
||||
|
||||
internal struct Config
|
||||
{
|
||||
/// <summary>
|
||||
/// Surface Color Format
|
||||
/// </summary>
|
||||
public ColorFormat color_format;
|
||||
/// <summary>
|
||||
/// Surface Depth Bits
|
||||
/// </summary>
|
||||
public DepthBits depth_bits;
|
||||
/// <summary>
|
||||
/// Surface Stencil Bits
|
||||
/// </summary>
|
||||
public StencilBits stencil_bits;
|
||||
/// <summary>
|
||||
/// Extra Surface Options
|
||||
/// </summary>
|
||||
public OptionsBits options_bits;
|
||||
/// <summary>
|
||||
/// Optional Surface MSAA Bits
|
||||
/// </summary>
|
||||
public MultisampleBits multisample_bits;
|
||||
#pragma warning disable 0169
|
||||
/// <summary>
|
||||
/// @internal Special flag for OpenGL-ES 1.1 indirect rendering surfaces
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Not used.
|
||||
/// </remarks>
|
||||
private ContextVersion gles_version;
|
||||
#pragma warning restore 0169
|
||||
}
|
||||
|
||||
internal struct NativeSurfaceOpenGL
|
||||
{
|
||||
// This structure is used to move data from one entity into another.
|
||||
#pragma warning disable 0169
|
||||
/// <summary>
|
||||
/// OpenGL texture id to use from glGenTextures().
|
||||
/// </summary>
|
||||
uint texture_id;
|
||||
/// <summary>
|
||||
/// 0 if not a FBO, FBO id otherwise from glGenFramebuffers().
|
||||
/// </summary>
|
||||
uint framebuffer_id;
|
||||
/// <summary>
|
||||
/// Same as 'internalFormat' for glTexImage2D().
|
||||
/// </summary>
|
||||
uint internal_format;
|
||||
/// <summary>
|
||||
/// Same as 'format' for glTexImage2D().
|
||||
/// </summary>
|
||||
uint format;
|
||||
/// <summary>
|
||||
/// Region inside the texture to use (image size is assumed as texture size,
|
||||
/// with 0, 0 being the top-left and co-ordinates working down to the right and bottom being positive).
|
||||
/// </summary>
|
||||
uint x;
|
||||
uint y;
|
||||
uint w;
|
||||
uint h;
|
||||
#pragma warning restore 0169
|
||||
}
|
||||
|
||||
internal enum ColorFormat
|
||||
{
|
||||
/// <summary>
|
||||
/// Opaque RGB surface
|
||||
/// </summary>
|
||||
RGB_888 = 0,
|
||||
/// <summary>
|
||||
/// RGBA surface with alpha
|
||||
/// </summary>
|
||||
RGBA_8888 = 1,
|
||||
/// <summary>
|
||||
/// Special value for creating PBuffer surfaces without any attached buffer.
|
||||
/// </summary>
|
||||
NO_FBO = 2
|
||||
}
|
||||
|
||||
internal enum DepthBits
|
||||
{
|
||||
NONE = 0,
|
||||
/// <summary>
|
||||
/// 8 bits precision surface depth
|
||||
/// </summary>
|
||||
BIT_8 = 1,
|
||||
/// <summary>
|
||||
/// 16 bits precision surface depth
|
||||
/// </summary>
|
||||
BIT_16 = 2,
|
||||
/// <summary>
|
||||
/// 24 bits precision surface depth
|
||||
/// </summary>
|
||||
BIT_24 = 3,
|
||||
/// <summary>
|
||||
/// 32 bits precision surface depth
|
||||
/// </summary>
|
||||
BIT_32 = 4
|
||||
}
|
||||
|
||||
internal enum StencilBits
|
||||
{
|
||||
NONE = 0,
|
||||
/// <summary>
|
||||
/// 1 bit precision for stencil buffer
|
||||
/// </summary>
|
||||
BIT_1 = 1,
|
||||
/// <summary>
|
||||
/// 2 bits precision for stencil buffer
|
||||
/// </summary>
|
||||
BIT_2 = 2,
|
||||
/// <summary>
|
||||
/// 4 bits precision for stencil buffer
|
||||
/// </summary>
|
||||
BIT_4 = 3,
|
||||
/// <summary>
|
||||
/// 8 bits precision for stencil buffer
|
||||
/// </summary>
|
||||
BIT_8 = 4,
|
||||
/// <summary>
|
||||
/// 16 bits precision for stencil buffer
|
||||
/// </summary>
|
||||
BIT_16 = 5
|
||||
}
|
||||
|
||||
internal enum OptionsBits
|
||||
{
|
||||
/// <summary>
|
||||
/// No extra options.
|
||||
/// </summary>
|
||||
NONE = 0,
|
||||
/// <summary>
|
||||
/// Optional hint to allow rendering directly to the Evas window if possible.
|
||||
/// </summary>
|
||||
DIRECT = (1 << 0),
|
||||
/// <summary>
|
||||
/// Force direct rendering even if the canvas is rotated.
|
||||
/// </summary>
|
||||
CLIENT_SIDE_ROTATION = (1 << 1),
|
||||
/// <summary>
|
||||
/// If enabled, Evas GL pixel callback will be called by another thread instead of main thread.
|
||||
/// </summary>
|
||||
THREAD = (1 << 2)
|
||||
}
|
||||
|
||||
internal enum MultisampleBits
|
||||
{
|
||||
/// <summary>
|
||||
/// No multisample rendering.
|
||||
/// </summary>
|
||||
NONE = 0,
|
||||
/// <summary>
|
||||
/// MSAA with minimum number of samples.
|
||||
/// </summary>
|
||||
LOW = 1,
|
||||
/// <summary>
|
||||
/// MSAA with half the maximum number of samples.
|
||||
/// </summary>
|
||||
MED = 2,
|
||||
/// <summary>
|
||||
/// MSAA with maximum allowed samples.
|
||||
/// </summary>
|
||||
HIGH = 3
|
||||
}
|
||||
|
||||
internal enum ContextVersion
|
||||
{
|
||||
/// <summary>
|
||||
/// OpenGL-ES 1.x
|
||||
/// </summary>
|
||||
GLES_1_X = 1,
|
||||
/// <summary>
|
||||
/// OpenGL-ES 2.x is the default
|
||||
/// </summary>
|
||||
GLES_2_X = 2,
|
||||
/// <summary>
|
||||
/// OpenGL-ES 3.x (@b Since 2.4)
|
||||
/// </summary>
|
||||
GLES_3_X = 3,
|
||||
/// <summary>
|
||||
/// Enable debug mode on this context (See GL_KHR_debug) (@b Since 4.0)
|
||||
/// </summary>
|
||||
DEBUG = 0x1000
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,90 +0,0 @@
|
|||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
internal static partial class Interop
|
||||
{
|
||||
internal static partial class Evas
|
||||
{
|
||||
internal static partial class Image
|
||||
{
|
||||
[DllImport(Libraries.Evas)]
|
||||
internal static extern IntPtr evas_object_image_add(IntPtr obj);
|
||||
|
||||
[DllImport(Libraries.Evas)]
|
||||
internal static extern IntPtr evas_object_image_filled_add(IntPtr obj);
|
||||
|
||||
[DllImport(Libraries.Evas)]
|
||||
internal static extern void evas_object_image_size_get(IntPtr obj, IntPtr x, out int y);
|
||||
|
||||
[DllImport(Libraries.Evas)]
|
||||
internal static extern void evas_object_image_size_get(IntPtr obj, out int x, IntPtr y);
|
||||
|
||||
[DllImport(Libraries.Evas)]
|
||||
internal static extern void evas_object_image_size_get(IntPtr obj, out int x, out int y);
|
||||
|
||||
[DllImport(Libraries.Evas)]
|
||||
internal static extern void evas_object_image_size_set(IntPtr obj, int w, int h);
|
||||
|
||||
[DllImport(Libraries.Evas)]
|
||||
internal static extern IntPtr evas_object_image_data_get(IntPtr obj, bool for_writing);
|
||||
|
||||
[DllImport(Libraries.Evas)]
|
||||
internal static extern void evas_object_image_data_set(IntPtr obj, IntPtr data);
|
||||
|
||||
[DllImport(Libraries.Evas)]
|
||||
internal static extern void evas_object_image_data_update_add(IntPtr obj, int x, int y, int w, int h);
|
||||
|
||||
[DllImport(Libraries.Evas)]
|
||||
internal static extern void evas_object_image_colorspace_set(IntPtr obj, Colorspace cspace);
|
||||
|
||||
[DllImport(Libraries.Evas)]
|
||||
internal static extern void evas_object_image_fill_set(IntPtr obj, int x, int y, int w, int h);
|
||||
|
||||
[DllImport(Libraries.Evas)]
|
||||
internal static extern void evas_object_image_native_surface_set(IntPtr obj, ref GL.NativeSurfaceOpenGL surf);
|
||||
|
||||
[DllImport(Libraries.Evas)]
|
||||
internal static extern void evas_object_image_native_surface_set(IntPtr obj, IntPtr zero);
|
||||
|
||||
[DllImport(Libraries.Evas)]
|
||||
internal static extern void evas_object_image_pixels_dirty_set(IntPtr obj, bool dirty);
|
||||
|
||||
[DllImport(Libraries.Evas)]
|
||||
internal static extern void evas_object_image_pixels_get_callback_set(IntPtr obj, ImagePixelsSetCallback func, IntPtr data);
|
||||
|
||||
[DllImport(Libraries.Evas)]
|
||||
internal static extern void evas_object_image_pixels_get_callback_set(IntPtr obj, IntPtr zero, IntPtr data);
|
||||
|
||||
[DllImport(Libraries.Evas)]
|
||||
internal static extern void evas_object_image_smooth_scale_set(IntPtr obj, bool smooth_scale);
|
||||
|
||||
[DllImport(Libraries.Evas)]
|
||||
internal static extern void evas_object_image_alpha_set(IntPtr obj, bool has_alpha);
|
||||
|
||||
public delegate void ImagePixelsSetCallback(IntPtr data, IntPtr o);
|
||||
|
||||
internal enum Colorspace
|
||||
{
|
||||
ARGB8888,
|
||||
YCBCR422P601_PL,
|
||||
YCBCR422P709_PL,
|
||||
RGB565_A5P,
|
||||
GRY8 = 4,
|
||||
YCBCR422601_PL,
|
||||
YCBCR420NV12601_PL,
|
||||
YCBCR420TM12601_PL,
|
||||
AGRY88 = 8,
|
||||
ETC1 = 9,
|
||||
RGB8_ETC2 = 10,
|
||||
RGBA8_ETC2_EAC = 11,
|
||||
ETC1_ALPHA = 12,
|
||||
RGB_S3TC_DXT1 = 13,
|
||||
RGBA_S3TC_DXT1 = 14,
|
||||
RGBA_S3TC_DXT2 = 15,
|
||||
RGBA_S3TC_DXT3 = 16,
|
||||
RGBA_S3TC_DXT4 = 17,
|
||||
RGBA_S3TC_DXT5 = 18,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
internal static partial class Interop
|
||||
{
|
||||
internal static partial class Evas
|
||||
{
|
||||
[DllImport(Libraries.Evas)]
|
||||
internal static extern IntPtr evas_object_evas_get(IntPtr obj);
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
internal static partial class Interop
|
||||
|
||||
namespace SkiaSharp.Views.Tizen.Interop
|
||||
{
|
||||
private static class Libraries
|
||||
internal static class Libraries
|
||||
{
|
||||
internal const string Libc = "libc.so.6";
|
||||
internal const string Evas = "libevas.so.1";
|
|
@ -1,17 +1,8 @@
|
|||
namespace SkiaSharp.Views.Tizen
|
||||
{
|
||||
/// <summary>
|
||||
/// Rendering mode used by the CustomRenderingView.
|
||||
/// </summary>
|
||||
public enum RenderingMode
|
||||
{
|
||||
/// <summary>
|
||||
/// View decides when to repaint the surface.
|
||||
/// </summary>
|
||||
Continuously,
|
||||
/// <summary>
|
||||
/// Surface is repainted on demand.
|
||||
/// </summary>
|
||||
WhenDirty,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,60 +1,36 @@
|
|||
using ElmSharp;
|
||||
using System;
|
||||
using System;
|
||||
using ElmSharp;
|
||||
using SkiaSharp.Views.Tizen.Interop;
|
||||
|
||||
namespace SkiaSharp.Views.Tizen
|
||||
{
|
||||
/// <summary>
|
||||
/// Software rendering for Skia.
|
||||
/// </summary>
|
||||
public class SKCanvasView : CustomRenderingView
|
||||
{
|
||||
/// <summary>
|
||||
/// Backing field for IgnorePixelScaling.
|
||||
/// </summary>
|
||||
private bool ignorePixelScaling;
|
||||
private SKImageInfo info;
|
||||
|
||||
/// <summary>
|
||||
/// Information about the surface.
|
||||
/// </summary>
|
||||
private SKImageInfo info = new SKImageInfo(0, 0, SKImageInfo.PlatformColorType, SKAlphaType.Premul);
|
||||
|
||||
/// <summary>
|
||||
/// Creates new instance with the given object as its parent.
|
||||
/// </summary>
|
||||
/// <param name="parent">The parent object.</param>
|
||||
public SKCanvasView(EvasObject parent) : base(parent)
|
||||
public SKCanvasView(EvasObject parent)
|
||||
: base(parent)
|
||||
{
|
||||
info = new SKImageInfo(0, 0, SKImageInfo.PlatformColorType, SKAlphaType.Premul);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If set to true, the surface is resized to device independent pixels, and then stretched to fill the view.
|
||||
/// If set to false, the surface is resized to 1 canvas pixel per display pixel.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Default value is false.
|
||||
/// </remarks>
|
||||
public bool IgnorePixelScaling
|
||||
{
|
||||
get
|
||||
{
|
||||
return ignorePixelScaling;
|
||||
}
|
||||
|
||||
get { return ignorePixelScaling; }
|
||||
set
|
||||
{
|
||||
if (ignorePixelScaling != value)
|
||||
{
|
||||
ignorePixelScaling = value;
|
||||
OnSurfaceSizeChanged();
|
||||
OnResized();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public event EventHandler<SKPaintSurfaceEventArgs> PaintSurface;
|
||||
|
||||
protected sealed override int SurfaceWidth => info.Width;
|
||||
|
||||
protected sealed override int SurfaceHeight => info.Height;
|
||||
protected override SKSizeI GetSurfaceSize() => info.Size;
|
||||
|
||||
protected virtual void OnDrawFrame(SKSurface surface, SKImageInfo info)
|
||||
{
|
||||
|
@ -64,7 +40,7 @@ namespace SkiaSharp.Views.Tizen
|
|||
protected sealed override void OnDrawFrame()
|
||||
{
|
||||
// draw directly into the EFL image data
|
||||
using (var surface = SKSurface.Create(info, Interop.Evas.Image.evas_object_image_data_get(EvasImage, true), info.RowBytes))
|
||||
using (var surface = SKSurface.Create(info, Evas.evas_object_image_data_get(evasImage, true), info.RowBytes))
|
||||
{
|
||||
// draw using SkiaSharp
|
||||
OnDrawFrame(surface, info);
|
||||
|
|
|
@ -2,66 +2,48 @@
|
|||
using System.Runtime.InteropServices;
|
||||
using ElmSharp;
|
||||
using SkiaSharp.Views.GlesInterop;
|
||||
using SkiaSharp.Views.Tizen.Interop;
|
||||
|
||||
namespace SkiaSharp.Views.Tizen
|
||||
{
|
||||
/// <summary>
|
||||
/// OpenGL surface for Skia.
|
||||
/// </summary>
|
||||
public class SKGLSurfaceView : CustomRenderingView
|
||||
{
|
||||
// EFL-related members
|
||||
private readonly Interop.Evas.GL.Config glConfig = new Interop.Evas.GL.Config()
|
||||
{
|
||||
color_format = Interop.Evas.GL.ColorFormat.RGBA_8888,
|
||||
depth_bits = Interop.Evas.GL.DepthBits.BIT_24,
|
||||
stencil_bits = Interop.Evas.GL.StencilBits.BIT_8,
|
||||
options_bits = Interop.Evas.GL.OptionsBits.NONE,
|
||||
multisample_bits = Interop.Evas.GL.MultisampleBits.HIGH,
|
||||
};
|
||||
private readonly Evas.Config glConfig;
|
||||
|
||||
// pointer to glConfig passed to the native side
|
||||
private IntPtr unmanagedGlConfig;
|
||||
|
||||
// connects the EFL with OpenGL
|
||||
private IntPtr glConfigPtr;
|
||||
private IntPtr glEvas;
|
||||
|
||||
// drawing context
|
||||
private IntPtr glContext;
|
||||
|
||||
// EFL wrapper for a OpenGL surface
|
||||
private IntPtr glSurface;
|
||||
|
||||
// Skia-related members
|
||||
private GRContext context;
|
||||
private GRBackendRenderTargetDesc renderTarget;
|
||||
|
||||
private GRBackendRenderTargetDesc renderTarget = new GRBackendRenderTargetDesc
|
||||
public SKGLSurfaceView(EvasObject parent)
|
||||
: base(parent)
|
||||
{
|
||||
Config = GRPixelConfig.Unknown,
|
||||
Origin = GRSurfaceOrigin.BottomLeft,
|
||||
};
|
||||
glConfig = new Evas.Config()
|
||||
{
|
||||
color_format = Evas.ColorFormat.RGBA_8888,
|
||||
depth_bits = Evas.DepthBits.BIT_24,
|
||||
stencil_bits = Evas.StencilBits.BIT_8,
|
||||
options_bits = Evas.OptionsBits.NONE,
|
||||
multisample_bits = Evas.MultisampleBits.HIGH,
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Creates new instance with the given object as its parent.
|
||||
/// </summary>
|
||||
/// <param name="parent">The parent object.</param>
|
||||
public SKGLSurfaceView(EvasObject parent) : base(parent)
|
||||
{
|
||||
var isBgra = SKImageInfo.PlatformColorType == SKColorType.Bgra8888;
|
||||
renderTarget = new GRBackendRenderTargetDesc
|
||||
{
|
||||
Config = isBgra ? GRPixelConfig.Bgra8888 : GRPixelConfig.Rgba8888,
|
||||
Origin = GRSurfaceOrigin.BottomLeft,
|
||||
};
|
||||
}
|
||||
|
||||
public event EventHandler<SKPaintGLSurfaceEventArgs> PaintSurface;
|
||||
|
||||
public GRContext GRContext => context;
|
||||
|
||||
protected sealed override int SurfaceWidth => renderTarget.Width;
|
||||
protected override SKSizeI GetSurfaceSize() => renderTarget.Size;
|
||||
|
||||
protected sealed override int SurfaceHeight => renderTarget.Height;
|
||||
|
||||
/// <summary>
|
||||
/// Performs the drawing to the specified surface.
|
||||
/// </summary>
|
||||
/// <param name="surface">Surface to draw to.</param>
|
||||
/// <param name="renderTarget">Description of the rendering context.</param>
|
||||
protected virtual void OnDrawFrame(SKSurface surface, GRBackendRenderTargetDesc renderTarget)
|
||||
{
|
||||
PaintSurface?.Invoke(this, new SKPaintGLSurfaceEventArgs(surface, renderTarget));
|
||||
|
@ -99,18 +81,18 @@ namespace SkiaSharp.Views.Tizen
|
|||
|
||||
protected sealed override bool UpdateSurfaceSize(Rect geometry)
|
||||
{
|
||||
if (geometry.Width != renderTarget.Width || geometry.Height != renderTarget.Height)
|
||||
var changed =
|
||||
geometry.Width != renderTarget.Width ||
|
||||
geometry.Height != renderTarget.Height;
|
||||
|
||||
if (changed)
|
||||
{
|
||||
// size has changed, update geometry
|
||||
renderTarget.Width = geometry.Width;
|
||||
renderTarget.Height = geometry.Height;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
|
||||
protected sealed override void CreateDrawingSurface()
|
||||
|
@ -128,14 +110,14 @@ namespace SkiaSharp.Views.Tizen
|
|||
if (glEvas == IntPtr.Zero)
|
||||
{
|
||||
// initialize the OpenGL (the EFL way)
|
||||
glEvas = Interop.Evas.GL.evas_gl_new(Interop.Evas.evas_object_evas_get(parent));
|
||||
glEvas = Evas.evas_gl_new(Interop.Evas.evas_object_evas_get(parent));
|
||||
|
||||
// copy the configuration to the native side
|
||||
unmanagedGlConfig = Marshal.AllocHGlobal(Marshal.SizeOf(glConfig));
|
||||
Marshal.StructureToPtr(glConfig, unmanagedGlConfig, false);
|
||||
glConfigPtr = Marshal.AllocHGlobal(Marshal.SizeOf(glConfig));
|
||||
Marshal.StructureToPtr(glConfig, glConfigPtr, false);
|
||||
|
||||
// initialize the context
|
||||
glContext = Interop.Evas.GL.evas_gl_context_create(glEvas, IntPtr.Zero);
|
||||
glContext = Evas.evas_gl_context_create(glEvas, IntPtr.Zero);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -144,15 +126,15 @@ namespace SkiaSharp.Views.Tizen
|
|||
if (glEvas != IntPtr.Zero)
|
||||
{
|
||||
// destroy the context
|
||||
Interop.Evas.GL.evas_gl_context_destroy(glEvas, glContext);
|
||||
Evas.evas_gl_context_destroy(glEvas, glContext);
|
||||
glContext = IntPtr.Zero;
|
||||
|
||||
// release the unmanaged memory
|
||||
Marshal.FreeHGlobal(unmanagedGlConfig);
|
||||
unmanagedGlConfig = IntPtr.Zero;
|
||||
Marshal.FreeHGlobal(glConfigPtr);
|
||||
glConfigPtr = IntPtr.Zero;
|
||||
|
||||
// destroy the EFL wrapper
|
||||
Interop.Evas.GL.evas_gl_free(glEvas);
|
||||
Evas.evas_gl_free(glEvas);
|
||||
glEvas = IntPtr.Zero;
|
||||
}
|
||||
}
|
||||
|
@ -162,22 +144,27 @@ namespace SkiaSharp.Views.Tizen
|
|||
if (glSurface == IntPtr.Zero)
|
||||
{
|
||||
// create the surface
|
||||
glSurface = Interop.Evas.GL.evas_gl_surface_create(glEvas, unmanagedGlConfig, renderTarget.Width, renderTarget.Height);
|
||||
glSurface = Evas.evas_gl_surface_create(glEvas, glConfigPtr, renderTarget.Width, renderTarget.Height);
|
||||
|
||||
// copy the native surface to the image
|
||||
Interop.Evas.GL.NativeSurfaceOpenGL nativeSurface;
|
||||
Interop.Evas.GL.evas_gl_native_surface_get(glEvas, glSurface, out nativeSurface);
|
||||
Interop.Evas.Image.evas_object_image_native_surface_set(EvasImage, ref nativeSurface);
|
||||
Evas.NativeSurfaceOpenGL nativeSurface;
|
||||
Evas.evas_gl_native_surface_get(glEvas, glSurface, out nativeSurface);
|
||||
Evas.evas_object_image_native_surface_set(evasImage, ref nativeSurface);
|
||||
|
||||
// switch to the current OpenGL context
|
||||
Interop.Evas.GL.evas_gl_make_current(glEvas, glSurface, glContext);
|
||||
Evas.evas_gl_make_current(glEvas, glSurface, glContext);
|
||||
|
||||
// resize the viewport
|
||||
Gles.glViewport(0, 0, renderTarget.Width, renderTarget.Height);
|
||||
|
||||
// initialize the Skia's context
|
||||
CreateContext();
|
||||
FillRenderTarget();
|
||||
|
||||
// copy the properties of the current surface
|
||||
var currentRenderTarget = SKGLDrawable.CreateRenderTarget();
|
||||
renderTarget.SampleCount = currentRenderTarget.SampleCount;
|
||||
renderTarget.StencilBits = currentRenderTarget.StencilBits;
|
||||
renderTarget.RenderTargetHandle = currentRenderTarget.RenderTargetHandle;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -189,10 +176,10 @@ namespace SkiaSharp.Views.Tizen
|
|||
DestroyContext();
|
||||
|
||||
// disconnect the surface from the image
|
||||
Interop.Evas.Image.evas_object_image_native_surface_set(EvasImage, IntPtr.Zero);
|
||||
Evas.evas_object_image_native_surface_set(evasImage, IntPtr.Zero);
|
||||
|
||||
// destroy the surface
|
||||
Interop.Evas.GL.evas_gl_surface_destroy(glEvas, glSurface);
|
||||
Evas.evas_gl_surface_destroy(glEvas, glSurface);
|
||||
glSurface = IntPtr.Zero;
|
||||
}
|
||||
}
|
||||
|
@ -213,48 +200,5 @@ namespace SkiaSharp.Views.Tizen
|
|||
context = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void FillRenderTarget()
|
||||
{
|
||||
// copy the properties of the current surface
|
||||
var currentRenderTarget = SKGLDrawable.CreateRenderTarget();
|
||||
renderTarget.SampleCount = currentRenderTarget.SampleCount;
|
||||
renderTarget.StencilBits = currentRenderTarget.StencilBits;
|
||||
renderTarget.RenderTargetHandle = currentRenderTarget.RenderTargetHandle;
|
||||
|
||||
GuessPixelFormat();
|
||||
}
|
||||
|
||||
private void GuessPixelFormat()
|
||||
{
|
||||
if (renderTarget.Config != GRPixelConfig.Unknown)
|
||||
{
|
||||
// already set, nothing to do
|
||||
return;
|
||||
}
|
||||
|
||||
// emulator and target use different versions of pixel format
|
||||
// try to guess which one is available by creating a surface
|
||||
|
||||
foreach (var config in new GRPixelConfig[] { GRPixelConfig.Rgba8888, GRPixelConfig.Bgra8888 })
|
||||
{
|
||||
if (renderTarget.Config == GRPixelConfig.Unknown)
|
||||
{
|
||||
renderTarget.Config = config;
|
||||
using (var surface = SKSurface.Create(context, renderTarget))
|
||||
{
|
||||
if (surface == null)
|
||||
{
|
||||
renderTarget.Config = GRPixelConfig.Unknown;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (renderTarget.Config == GRPixelConfig.Unknown)
|
||||
{
|
||||
throw new InvalidOperationException("Context does not support neither RGBA8888 nor BGRA8888 pixel format");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,52 +1,34 @@
|
|||
using ElmSharp;
|
||||
using System;
|
||||
|
||||
using TSystemInfo = Tizen.System.SystemInfo;
|
||||
using ElmSharp;
|
||||
using Tizen.System;
|
||||
|
||||
namespace SkiaSharp.Views.Tizen
|
||||
{
|
||||
public static class ScalingInfo
|
||||
{
|
||||
private static Lazy<string> s_profile = new Lazy<string>(() =>
|
||||
{
|
||||
return Elementary.GetProfile();
|
||||
});
|
||||
public static class ScalingInfo
|
||||
{
|
||||
private static readonly Lazy<string> profile = new Lazy<string>(() => Elementary.GetProfile());
|
||||
|
||||
/// <summary>
|
||||
/// DPI of the screen.
|
||||
/// </summary>
|
||||
private static Lazy<int> s_dpi = new Lazy<int>(() =>
|
||||
private static readonly Lazy<int> dpi = new Lazy<int>(() =>
|
||||
{
|
||||
// TV has fixed DPI value (72)
|
||||
if (Profile == "tv")
|
||||
{
|
||||
// TV has fixed DPI value (72)
|
||||
return 72;
|
||||
}
|
||||
|
||||
int dpi = 0;
|
||||
TSystemInfo.TryGetValue("http://tizen.org/feature/screen.dpi", out dpi);
|
||||
SystemInfo.TryGetValue("http://tizen.org/feature/screen.dpi", out int dpi);
|
||||
return dpi;
|
||||
});
|
||||
|
||||
/// <summary>
|
||||
/// Scaling factor, allows to convert pixels to Android-style device-independent pixels.
|
||||
/// </summary>
|
||||
private static Lazy<float> s_scalingFactor = new Lazy<float>(() => s_dpi.Value / 160.0f);
|
||||
// allows to convert pixels to Android-style device-independent pixels
|
||||
private static readonly Lazy<float> scalingFactor = new Lazy<float>(() => dpi.Value / 160.0f);
|
||||
|
||||
public static string Profile => s_profile.Value;
|
||||
public static string Profile => profile.Value;
|
||||
|
||||
public static int DPI => s_dpi.Value;
|
||||
public static int Dpi => dpi.Value;
|
||||
|
||||
public static float ScalingFactor => s_scalingFactor.Value;
|
||||
public static float ScalingFactor => scalingFactor.Value;
|
||||
|
||||
public static float FromPixel(float v)
|
||||
{
|
||||
return v / ScalingFactor;
|
||||
}
|
||||
public static float FromPixel(float v) => v / ScalingFactor;
|
||||
|
||||
public static float ToPixel(float v)
|
||||
{
|
||||
return v * ScalingFactor;
|
||||
}
|
||||
public static float ToPixel(float v) => v * ScalingFactor;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
using ElmSharp;
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace SkiaSharp.Views.Tizen
|
||||
{
|
||||
public static class TizenExtensions
|
||||
{
|
||||
// Point*
|
||||
// Point
|
||||
|
||||
public static SKPoint ToSKPoint(this Point point)
|
||||
{
|
||||
return new SKPoint(point.X, point.Y);
|
||||
|
@ -19,15 +18,16 @@ namespace SkiaSharp.Views.Tizen
|
|||
|
||||
public static Point ToPoint(this SKPoint point)
|
||||
{
|
||||
return new Point() { X = (int)point.X, Y = (int)point.Y };
|
||||
return new Point { X = (int)point.X, Y = (int)point.Y };
|
||||
}
|
||||
|
||||
public static Point ToPoint(this SKPointI point)
|
||||
{
|
||||
return new Point() { X = point.X, Y = point.Y };
|
||||
return new Point { X = point.X, Y = point.Y };
|
||||
}
|
||||
|
||||
// Rectangle*
|
||||
// Rectangle
|
||||
|
||||
public static SKRect ToSKRect(this Rect rect)
|
||||
{
|
||||
return new SKRect(rect.Left, rect.Top, rect.Right, rect.Bottom);
|
||||
|
@ -49,6 +49,7 @@ namespace SkiaSharp.Views.Tizen
|
|||
}
|
||||
|
||||
// Color
|
||||
|
||||
public static SKColor ToSKColor(this Color color)
|
||||
{
|
||||
return new SKColor((byte)color.R, (byte)color.G, (byte)color.B, (byte)color.A);
|
||||
|
@ -58,26 +59,5 @@ namespace SkiaSharp.Views.Tizen
|
|||
{
|
||||
return Color.FromRgba(color.Red, color.Green, color.Blue, color.Alpha);
|
||||
}
|
||||
|
||||
// Matrix
|
||||
public static Stream ToStream(this SKBitmap skiaBitmap)
|
||||
{
|
||||
return ToStream(SKImage.FromBitmap(skiaBitmap));
|
||||
}
|
||||
|
||||
public static Stream ToStream(this SKPixmap skiaPixmap)
|
||||
{
|
||||
return ToStream(SKImage.FromPixels(skiaPixmap));
|
||||
}
|
||||
|
||||
public static Stream ToStream(this SKImage skiaImage)
|
||||
{
|
||||
return skiaImage.Encode().AsStream();
|
||||
}
|
||||
|
||||
public static Stream ToStream(this SKPicture skiaPicture, SKSizeI dimensions)
|
||||
{
|
||||
return ToStream(SKImage.FromPicture(skiaPicture, dimensions));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче