Moved a few types around and tweaked the APIs a bit to match the others

This commit is contained in:
Matthew Leibowitz 2018-05-01 22:46:00 +02:00
Родитель 9d4f672584
Коммит 1d7290a627
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 3650EBE4AA155AF9
17 изменённых файлов: 348 добавлений и 773 удалений

Просмотреть файл

@ -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));
}
}
}