diff --git a/binding/HarfBuzzSharp.Tizen/HarfBuzzSharp.Tizen.csproj b/binding/HarfBuzzSharp.Tizen/HarfBuzzSharp.Tizen.csproj new file mode 100755 index 00000000..675d5802 --- /dev/null +++ b/binding/HarfBuzzSharp.Tizen/HarfBuzzSharp.Tizen.csproj @@ -0,0 +1,39 @@ + + + + + netstandard2.0 + false + HarfBuzzSharp + tizen40 + + + + full + bin\Debug + + + pdbonly + bin\Release + + + + + + Runtime + + + + + + + nuget\runtimes\tizen-armel\native\libHarfBuzzSharp.so + + + nuget\runtimes\linux-x86\native\libHarfBuzzSharp.so + + + + + + diff --git a/binding/HarfBuzzSharp.sln b/binding/HarfBuzzSharp.sln old mode 100644 new mode 100755 index 7a709259..33aaa846 --- a/binding/HarfBuzzSharp.sln +++ b/binding/HarfBuzzSharp.sln @@ -23,6 +23,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HarfBuzzSharp.NetStandard", EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HarfBuzzSharp.UWP", "HarfBuzzSharp.UWP\HarfBuzzSharp.UWP.csproj", "{6D1E1F39-EF70-4211-A518-BBBAF02D6FFF}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HarfBuzzSharp.Tizen", "HarfBuzzSharp.Tizen\HarfBuzzSharp.Tizen.csproj", "{D0CBD4FC-4329-4D79-959B-47FDCFAE2869}" +EndProject Global GlobalSection(SharedMSBuildProjectFiles) = preSolution HarfBuzzSharp.Shared\HarfBuzzSharp.Shared.projitems*{1aaa8f60-6138-4dfe-b240-5a0f3fb87e0f}*SharedItemsImports = 13 @@ -77,6 +79,10 @@ Global {6D1E1F39-EF70-4211-A518-BBBAF02D6FFF}.Debug|Any CPU.Build.0 = Debug|Any CPU {6D1E1F39-EF70-4211-A518-BBBAF02D6FFF}.Release|Any CPU.ActiveCfg = Release|Any CPU {6D1E1F39-EF70-4211-A518-BBBAF02D6FFF}.Release|Any CPU.Build.0 = Release|Any CPU + {D0CBD4FC-4329-4D79-959B-47FDCFAE2869}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D0CBD4FC-4329-4D79-959B-47FDCFAE2869}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D0CBD4FC-4329-4D79-959B-47FDCFAE2869}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D0CBD4FC-4329-4D79-959B-47FDCFAE2869}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/binding/SkiaSharp.Tizen/SkiaSharp.Tizen.csproj b/binding/SkiaSharp.Tizen/SkiaSharp.Tizen.csproj new file mode 100755 index 00000000..b7fc4c63 --- /dev/null +++ b/binding/SkiaSharp.Tizen/SkiaSharp.Tizen.csproj @@ -0,0 +1,39 @@ + + + + + netstandard2.0 + false + SkiaSharp + tizen40 + + + + full + bin\Debug + + + pdbonly + bin\Release + + + + + + Runtime + + + + + + + nuget\runtimes\tizen-armel\native\libSkiaSharp.so + + + nuget\runtimes\linux-x86\native\libSkiaSharp.so + + + + + + diff --git a/binding/SkiaSharp.sln b/binding/SkiaSharp.sln old mode 100644 new mode 100755 index 7d628135..c9621f40 --- a/binding/SkiaSharp.sln +++ b/binding/SkiaSharp.sln @@ -23,6 +23,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SkiaSharp.NetStandard", "Sk EndProject Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "Binding.Shared", "Binding.Shared\Binding.Shared.shproj", "{6F8349DC-90AC-441D-8B8B-BE623F46BE6D}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SkiaSharp.Tizen", "SkiaSharp.Tizen\SkiaSharp.Tizen.csproj", "{A48813C8-9C4A-477F-A34C-FCAFFE751037}" +EndProject Global GlobalSection(SharedMSBuildProjectFiles) = preSolution binding\Binding.projitems*{4588a759-3853-49b8-8a68-6c7917be9220}*SharedItemsImports = 4 @@ -78,6 +80,10 @@ Global {4E0924F8-D546-4428-9412-4B9411FBA5FF}.Debug|Any CPU.Build.0 = Debug|Any CPU {4E0924F8-D546-4428-9412-4B9411FBA5FF}.Release|Any CPU.ActiveCfg = Release|Any CPU {4E0924F8-D546-4428-9412-4B9411FBA5FF}.Release|Any CPU.Build.0 = Release|Any CPU + {A48813C8-9C4A-477F-A34C-FCAFFE751037}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A48813C8-9C4A-477F-A34C-FCAFFE751037}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A48813C8-9C4A-477F-A34C-FCAFFE751037}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A48813C8-9C4A-477F-A34C-FCAFFE751037}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/build.cake b/build.cake old mode 100644 new mode 100755 index 4b51c51d..40df0fa1 --- a/build.cake +++ b/build.cake @@ -31,6 +31,8 @@ string ANDROID_HOME = EnvironmentVariable ("ANDROID_HOME") ?? EnvironmentVariabl string ANDROID_SDK_ROOT = EnvironmentVariable ("ANDROID_SDK_ROOT") ?? ANDROID_HOME; string ANDROID_NDK_HOME = EnvironmentVariable ("ANDROID_NDK_HOME") ?? EnvironmentVariable ("HOME") + "/Library/Developer/Xamarin/android-ndk"; +string TIZEN_STUDIO_HOME = EnvironmentVariable ("TIZEN_STUDIO_HOME") ?? EnvironmentVariable ("HOME") + "/tizen-studio"; + DirectoryPath ROOT_PATH = MakeAbsolute(Directory(".")); DirectoryPath DEPOT_PATH = MakeAbsolute(ROOT_PATH.Combine("externals/depot_tools")); DirectoryPath SKIA_PATH = MakeAbsolute(ROOT_PATH.Combine("externals/skia")); @@ -188,6 +190,7 @@ Task ("samples") { "uwp", isWin }, { "watchos", isMac }, { "wpf", isWin }, + { "tizen", isLinux } }; var platformMatrix = new Dictionary { @@ -197,6 +200,7 @@ Task ("samples") { "watchos", "iPhoneSimulator" }, { "xamarin.forms.mac", "iPhone" }, { "xamarin.forms.windows", "x86" }, + { "xamarin.forms.tizen", "x86" } }; var buildSample = new Action (sln => { @@ -247,7 +251,8 @@ Task ("samples") var shouldBuild = (isLinux && slnPlatform == ".linux") || (isMac && slnPlatform == ".mac") || - (isWin && slnPlatform == ".windows"); + (isWin && slnPlatform == ".windows") || + (isLinux && slnPlatform == ".tizen"); if (shouldBuild) { buildSample (sln); } else { diff --git a/cake/BuildExternals.cake b/cake/BuildExternals.cake old mode 100644 new mode 100755 index 8976f23d..1d6302ec --- a/cake/BuildExternals.cake +++ b/cake/BuildExternals.cake @@ -49,6 +49,30 @@ void RunLipo (DirectoryPath directory, FilePath output, FilePath[] inputs) }); } +var BuildingForTizen = DirectoryExists (TIZEN_STUDIO_HOME) && IsRunningOnLinux (); + +var ReplaceConfigH = new Action ((newConfigH) => { + var oldConfigH = HARFBUZZ_PATH.CombineWithFilePath ("harfbuzz/config.h"); + + if (FileExists (oldConfigH)) { + MoveFile (oldConfigH, oldConfigH + ".bak"); + } + + CopyFile (newConfigH, oldConfigH); +}); + +var RestoreConfigH = new Action (() => { + var configH = HARFBUZZ_PATH.CombineWithFilePath ("harfbuzz/config.h"); + var backupConfigH = configH + ".bak"; + + if (FileExists (configH)) { + DeleteFile (configH); + } + + if (FileExists (backupConfigH)) { + MoveFile (backupConfigH, configH); + } +}); //////////////////////////////////////////////////////////////////////////////////////////////////// // EXTERNALS - the native C and C++ libraries //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -74,6 +98,7 @@ Task ("externals-native") .IsDependentOn ("externals-watchos") .IsDependentOn ("externals-android") .IsDependentOn ("externals-linux") + .IsDependentOn ("externals-tizen") .Does (() => { }); @@ -625,6 +650,70 @@ Task ("externals-linux") } }); +Task ("externals-tizen") + .IsDependentOn ("externals-init") + .WithCriteria (BuildingForTizen) + .Does (() => +{ + var tizen = MakeAbsolute (Directory (TIZEN_STUDIO_HOME)).CombineWithFilePath ("tools/ide/bin/tizen").FullPath; + + var buildArch = new Action ((arch, skiaArch) => { + + // generate native skia build files + GnNinja ($"tizen/{arch}", "skia", + $"'" + + $" is_official_build=true skia_enable_tools=false" + + $" target_os=\"linux\" target_cpu=\"{skiaArch}\"" + + $" building_for_tizen=true" + + $" skia_enable_gpu=true" + + $" skia_use_icu=false" + + $" skia_use_sfntly=false" + + $" skia_use_piex=true" + + $" skia_use_system_expat=false" + + $" skia_use_system_freetype2=true" + + $" skia_use_system_libjpeg_turbo=false" + + $" skia_use_system_libpng=false" + + $" skia_use_system_libwebp=false" + + $" skia_use_system_zlib=true" + + $" extra_cflags=[ \"-DSKIA_C_DLL\", \"-DOS_TIZEN\" ]" + + $" ncli=\"{TIZEN_STUDIO_HOME}\"" + + $" ncli_version=\"4.0\"" + + $"'"); + + // build libSkiaSharp + RunProcess (tizen, new ProcessSettings { + Arguments = "build-native -a " + skiaArch + " -c llvm -C Release" , + WorkingDirectory = ROOT_PATH.Combine ("native-builds/libSkiaSharp_tizen").FullPath, + }); + + // copy libSkiaSharp to output + var outDir = $"output/native/tizen/{arch}"; + CopyFile("native-builds/libSkiaSharp_tizen/Release/libskiasharp.so", "native-builds/libSkiaSharp_tizen/Release/libSkiaSharp.so"); + var libSkiaSharp = "native-builds/libSkiaSharp_tizen/Release/libSkiaSharp.so"; + EnsureDirectoryExists (outDir); + CopyFile (libSkiaSharp, $"{outDir}/libSkiaSharp.so"); + }); + + var buildHarfBuzzArch = new Action ((arch, skiaArch) => { + var build_path = ROOT_PATH.Combine ("native-builds/libHarfBuzzSharp_tizen").FullPath; + // build libHarfBuzzSharp + RunProcess(tizen, new ProcessSettings { + Arguments = "build-native -a " + skiaArch + " -c llvm -C Release", + WorkingDirectory = build_path, + }); + + // copy libHarfBuzzSharp to output + EnsureDirectoryExists ($"output/native/tizen/{arch}"); + var so = "native-builds/libHarfBuzzSharp_tizen/Release/libharfbuzzsharp.so"; + CopyFileToDirectory(so, $"output/native/tizen/{arch}"); + CopyFile (so, $"output/native/tizen/{arch}/libHarfBuzzSharp.so"); + }); + + buildArch ("armel", "arm"); + buildArch ("i386", "x86"); + buildHarfBuzzArch ("armel", "arm"); + buildHarfBuzzArch ("i386", "x86"); +}); //////////////////////////////////////////////////////////////////////////////////////////////////// // EXTERNALS DOWNLOAD - download any externals that are needed //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/native-builds/libHarfBuzzSharp_tizen/project_def.prop b/native-builds/libHarfBuzzSharp_tizen/project_def.prop new file mode 100755 index 00000000..6a504ec4 --- /dev/null +++ b/native-builds/libHarfBuzzSharp_tizen/project_def.prop @@ -0,0 +1,48 @@ +type = sharedLib +profile = mobile-4.0 + +APPNAME = HarfBuzzSharp + +USER_INC_DIRS = ../../externals/harfbuzz/harfbuzz/src/hb-ucdn \ + ../../externals/harfbuzz/harfbuzz/src \ + ../../externals/harfbuzz/harfbuzz + +USER_DEFS = HAVE_CONFIG_H + +USER_CPP_DEFS = $(USER_DEFS) + +USER_SRCS = ../../externals/harfbuzz/harfbuzz/src/hb-ucdn/ucdn.c \ + ../../externals/harfbuzz/harfbuzz/src/hb-blob.cc \ + ../../externals/harfbuzz/harfbuzz/src/hb-buffer-serialize.cc \ + ../../externals/harfbuzz/harfbuzz/src/hb-buffer.cc \ + ../../externals/harfbuzz/harfbuzz/src/hb-common.cc \ + ../../externals/harfbuzz/harfbuzz/src/hb-face.cc \ + ../../externals/harfbuzz/harfbuzz/src/hb-fallback-shape.cc \ + ../../externals/harfbuzz/harfbuzz/src/hb-font.cc \ + ../../externals/harfbuzz/harfbuzz/src/hb-ot-font.cc \ + ../../externals/harfbuzz/harfbuzz/src/hb-ot-layout.cc \ + ../../externals/harfbuzz/harfbuzz/src/hb-ot-map.cc \ + ../../externals/harfbuzz/harfbuzz/src/hb-ot-math.cc \ + ../../externals/harfbuzz/harfbuzz/src/hb-ot-shape-complex-arabic.cc \ + ../../externals/harfbuzz/harfbuzz/src/hb-ot-shape-complex-default.cc \ + ../../externals/harfbuzz/harfbuzz/src/hb-ot-shape-complex-hangul.cc \ + ../../externals/harfbuzz/harfbuzz/src/hb-ot-shape-complex-hebrew.cc \ + ../../externals/harfbuzz/harfbuzz/src/hb-ot-shape-complex-indic-table.cc \ + ../../externals/harfbuzz/harfbuzz/src/hb-ot-shape-complex-indic.cc \ + ../../externals/harfbuzz/harfbuzz/src/hb-ot-shape-complex-myanmar.cc \ + ../../externals/harfbuzz/harfbuzz/src/hb-ot-shape-complex-thai.cc \ + ../../externals/harfbuzz/harfbuzz/src/hb-ot-shape-complex-tibetan.cc \ + ../../externals/harfbuzz/harfbuzz/src/hb-ot-shape-complex-use-table.cc \ + ../../externals/harfbuzz/harfbuzz/src/hb-ot-shape-complex-use.cc \ + ../../externals/harfbuzz/harfbuzz/src/hb-ot-shape-fallback.cc \ + ../../externals/harfbuzz/harfbuzz/src/hb-ot-shape-normalize.cc \ + ../../externals/harfbuzz/harfbuzz/src/hb-ot-shape.cc \ + ../../externals/harfbuzz/harfbuzz/src/hb-ot-tag.cc \ + ../../externals/harfbuzz/harfbuzz/src/hb-ot-var.cc \ + ../../externals/harfbuzz/harfbuzz/src/hb-set.cc \ + ../../externals/harfbuzz/harfbuzz/src/hb-shape-plan.cc \ + ../../externals/harfbuzz/harfbuzz/src/hb-shape.cc \ + ../../externals/harfbuzz/harfbuzz/src/hb-shaper.cc \ + ../../externals/harfbuzz/harfbuzz/src/hb-ucdn.cc \ + ../../externals/harfbuzz/harfbuzz/src/hb-unicode.cc \ + ../../externals/harfbuzz/harfbuzz/src/hb-warning.cc diff --git a/native-builds/libSkiaSharp_tizen/project_def.prop b/native-builds/libSkiaSharp_tizen/project_def.prop new file mode 100755 index 00000000..5b90c30c --- /dev/null +++ b/native-builds/libSkiaSharp_tizen/project_def.prop @@ -0,0 +1,49 @@ +type = sharedLib +profile = mobile-4.0 + +USER_LIB_DIRS = ../../externals/skia/out/tizen/$(BUILD_ARCH) + +USER_LIBS = skia GLESv2 + +USER_LINK_OPTS = -Wl,--gc-sections + +APPNAME = SkiaSharp + +USER_INC_DIRS = ../../externals/skia/src/c \ + ../../externals/skia/src/core \ + ../../externals/skia/src/xml \ + ../../externals/skia/include/c \ + ../../externals/skia/include/core \ + ../../externals/skia/include/codec \ + ../../externals/skia/include/effects \ + ../../externals/skia/include/pathops \ + ../../externals/skia/include/gpu \ + ../../externals/skia/include/config \ + ../../externals/skia/include/xml \ + ../../externals/skia/include/svg \ + ../../externals/skia/include/utils \ + ../../externals/skia/include/ports \ + ../../externals/skia/include/private \ + ../../externals/skia/include/images \ + ../../externals/skia/include/xml \ + ../../externals/skia/include/xamarin + +USER_DEFS = SK_INTERNAL SK_GAMMA_APPLY_TO_A8 \ + SK_ALLOW_STATIC_GLOBAL_INITIALIZERS=0 SK_SUPPORT_GPU=1 \ + SK_BUILD_FOR_UNIX SKIA_C_DLL SKIA_IMPLEMENTATION=1 \ + NDEBUG + +USER_CPP_DEFS = $(USER_DEFS) + +USER_C_OPTS = -fPIC -g -fno-exceptions -fstrict-aliasing -Wall -Wextra \ + -Winit-self -Wpointer-arith -Wsign-compare -Wno-unused-parameter \ + -Werror -Os -ffunction-sections -fdata-sections -fno-rtti + +USER_CPP_OPTS = $(USER_C_OPTS) -std=c++11 -fno-threadsafe-statics -Wnon-virtual-dtor + +USER_SRCS = ../../externals/skia/src/xamarin/sk_xamarin.cpp \ + ../../externals/skia/src/xamarin/SkiaKeeper.c \ + ../../externals/skia/src/xamarin/sk_managedstream.cpp \ + ../../externals/skia/src/xamarin/sk_managedpixelserializer.cpp \ + ../../externals/skia/src/xamarin/SkManagedPixelSerializer.cpp \ + ../../externals/skia/src/xamarin/SkManagedStream.cpp diff --git a/nuget/HarfbuzzSharp.nuspec b/nuget/HarfbuzzSharp.nuspec old mode 100644 new mode 100755 index b9f729c8..a08c28a1 --- a/nuget/HarfbuzzSharp.nuspec +++ b/nuget/HarfbuzzSharp.nuspec @@ -58,6 +58,8 @@ Please visit https://go.microsoft.com/fwlink/?linkid=868517 to view the release + + diff --git a/nuget/SkiaSharp.Views.Forms.nuspec b/nuget/SkiaSharp.Views.Forms.nuspec old mode 100644 new mode 100755 index e1558d8d..f7f82846 --- a/nuget/SkiaSharp.Views.Forms.nuspec +++ b/nuget/SkiaSharp.Views.Forms.nuspec @@ -51,6 +51,11 @@ Please visit https://go.microsoft.com/fwlink/?linkid=868517 to view the release + + + + + @@ -67,7 +72,7 @@ Please visit https://go.microsoft.com/fwlink/?linkid=868517 to view the release - + diff --git a/nuget/SkiaSharp.Views.nuspec b/nuget/SkiaSharp.Views.nuspec old mode 100644 new mode 100755 index 9827ba6a..6d7f63d3 --- a/nuget/SkiaSharp.Views.nuspec +++ b/nuget/SkiaSharp.Views.nuspec @@ -52,7 +52,7 @@ Please visit https://go.microsoft.com/fwlink/?linkid=868517 to view the release - + diff --git a/nuget/SkiaSharp.nuspec b/nuget/SkiaSharp.nuspec old mode 100644 new mode 100755 index ec1d6608..c1da2ede --- a/nuget/SkiaSharp.nuspec +++ b/nuget/SkiaSharp.nuspec @@ -65,7 +65,8 @@ Please visit https://go.microsoft.com/fwlink/?linkid=868517 to view the release - + + diff --git a/samples/Basic/Xamarin.Forms/SkiaSharpSample.Tizen/SkiaSharpSample.Tizen.cs b/samples/Basic/Xamarin.Forms/SkiaSharpSample.Tizen/SkiaSharpSample.Tizen.cs new file mode 100755 index 00000000..a06ef840 --- /dev/null +++ b/samples/Basic/Xamarin.Forms/SkiaSharpSample.Tizen/SkiaSharpSample.Tizen.cs @@ -0,0 +1,21 @@ +using System; + +namespace SkiaSharpSample +{ + class Program : global::Xamarin.Forms.Platform.Tizen.FormsApplication + { + protected override void OnCreate() + { + base.OnCreate(); + + LoadApplication(new App()); + } + + static void Main(string[] args) + { + var app = new Program(); + global::Xamarin.Forms.Platform.Tizen.Forms.Init(app); + app.Run(args); + } + } +} diff --git a/samples/Basic/Xamarin.Forms/SkiaSharpSample.Tizen/SkiaSharpSample.Tizen.csproj b/samples/Basic/Xamarin.Forms/SkiaSharpSample.Tizen/SkiaSharpSample.Tizen.csproj new file mode 100755 index 00000000..bcdefe9e --- /dev/null +++ b/samples/Basic/Xamarin.Forms/SkiaSharpSample.Tizen/SkiaSharpSample.Tizen.csproj @@ -0,0 +1,52 @@ + + + + + tizen40 + Exe + + + + portable + bin\Debug\ + + + None + bin\Release\ + + + + + + + + + + + + + + + + + + + + + tpkroot\bin\runtimes\linux-x86\native\libSkiaSharp.so + Always + + + tpkroot\bin\runtimes\tizen-armel\native\libSkiaSharp.so + Always + + + + + + Runtime + + + + + diff --git a/samples/Basic/Xamarin.Forms/SkiaSharpSample.Tizen/shared/res/SkiaSharpSample.Tizen.png b/samples/Basic/Xamarin.Forms/SkiaSharpSample.Tizen/shared/res/SkiaSharpSample.Tizen.png new file mode 100755 index 00000000..9f3cb986 Binary files /dev/null and b/samples/Basic/Xamarin.Forms/SkiaSharpSample.Tizen/shared/res/SkiaSharpSample.Tizen.png differ diff --git a/samples/Basic/Xamarin.Forms/SkiaSharpSample.Tizen/tizen-manifest.xml b/samples/Basic/Xamarin.Forms/SkiaSharpSample.Tizen/tizen-manifest.xml new file mode 100755 index 00000000..662cd4cb --- /dev/null +++ b/samples/Basic/Xamarin.Forms/SkiaSharpSample.Tizen/tizen-manifest.xml @@ -0,0 +1,15 @@ + + + + + + SkiaSharpSample.Tizen.png + + + diff --git a/samples/Basic/Xamarin.Forms/SkiaSharpSample.sln b/samples/Basic/Xamarin.Forms/SkiaSharpSample.sln old mode 100644 new mode 100755 index eb4d973d..9dc9dc92 --- a/samples/Basic/Xamarin.Forms/SkiaSharpSample.sln +++ b/samples/Basic/Xamarin.Forms/SkiaSharpSample.sln @@ -63,6 +63,14 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SkiaSharpSample", "SkiaShar EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SkiaSharpSample.macOS", "SkiaSharpSample.macOS\SkiaSharpSample.macOS.csproj", "{1D7EC18C-1780-4C46-8736-A3661DA20AEE}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SkiaSharpSample.Tizen", "SkiaSharpSample.Tizen\SkiaSharpSample.Tizen.csproj", "{B7066619-8AF0-4980-A83D-49A8B9007523}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SkiaSharp.Tizen", "..\..\..\binding\SkiaSharp.Tizen\SkiaSharp.Tizen.csproj", "{A7B25831-3EA3-4F88-AA82-4D4CA66B19C6}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SkiaSharp.Views.Tizen", "..\..\..\source\SkiaSharp.Views\SkiaSharp.Views.Tizen\SkiaSharp.Views.Tizen.csproj", "{E0AAA975-BCF0-46F9-8E95-407FD6931850}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SkiaSharp.Views.Forms.Tizen", "..\..\..\source\SkiaSharp.Views.Forms\SkiaSharp.Views.Forms.Tizen\SkiaSharp.Views.Forms.Tizen.csproj", "{CB4BF122-0676-4487-A95D-3BA9E3CD6049}" +EndProject Global GlobalSection(SharedMSBuildProjectFiles) = preSolution ..\..\..\source\SkiaSharp.Views.Forms\SkiaSharp.Views.Forms.Native.Shared\SkiaSharp.Views.Forms.Native.Shared.projitems*{2f94f024-1841-47e8-b521-74aa4e3eba54}*SharedItemsImports = 4 diff --git a/samples/Gallery/Xamarin.Forms/Tizen/SkiaSharpGallery.Tizen.cs b/samples/Gallery/Xamarin.Forms/Tizen/SkiaSharpGallery.Tizen.cs new file mode 100755 index 00000000..a06ef840 --- /dev/null +++ b/samples/Gallery/Xamarin.Forms/Tizen/SkiaSharpGallery.Tizen.cs @@ -0,0 +1,21 @@ +using System; + +namespace SkiaSharpSample +{ + class Program : global::Xamarin.Forms.Platform.Tizen.FormsApplication + { + protected override void OnCreate() + { + base.OnCreate(); + + LoadApplication(new App()); + } + + static void Main(string[] args) + { + var app = new Program(); + global::Xamarin.Forms.Platform.Tizen.Forms.Init(app); + app.Run(args); + } + } +} diff --git a/samples/Gallery/Xamarin.Forms/Tizen/SkiaSharpGallery.Tizen.csproj b/samples/Gallery/Xamarin.Forms/Tizen/SkiaSharpGallery.Tizen.csproj new file mode 100755 index 00000000..82b6423d --- /dev/null +++ b/samples/Gallery/Xamarin.Forms/Tizen/SkiaSharpGallery.Tizen.csproj @@ -0,0 +1,64 @@ + + + + + tizen40 + Exe + + + + portable + bin\Debug\ + + + None + bin\Release\ + + + + + + + + + + + + + + + + + + + + + + + + tpkroot\bin\runtimes\linux-x86\native\libSkiaSharp.so + Always + + + tpkroot\bin\runtimes\tizen-armel\native\libSkiaSharp.so + Always + + + + tpkroot\bin\runtimes\linux-x86\native\libHarfBuzzSharp.so + Always + + + tpkroot\bin\runtimes\tizen-armel\native\libHarfBuzzSharp.so + Always + + + + + + Runtime + + + + + diff --git a/samples/Gallery/Xamarin.Forms/Tizen/shared/res/SkiaSharpGallery.Tizen.png b/samples/Gallery/Xamarin.Forms/Tizen/shared/res/SkiaSharpGallery.Tizen.png new file mode 100755 index 00000000..9f3cb986 Binary files /dev/null and b/samples/Gallery/Xamarin.Forms/Tizen/shared/res/SkiaSharpGallery.Tizen.png differ diff --git a/samples/Gallery/Xamarin.Forms/Tizen/tizen-manifest.xml b/samples/Gallery/Xamarin.Forms/Tizen/tizen-manifest.xml new file mode 100755 index 00000000..2c0a0e03 --- /dev/null +++ b/samples/Gallery/Xamarin.Forms/Tizen/tizen-manifest.xml @@ -0,0 +1,15 @@ + + + + + + SkiaSharpGallery.Tizen.png + + + diff --git a/source/SkiaSharp.Views.Forms/SkiaSharp.Views.Forms.Native.Shared/SKCanvasViewRendererBase.cs b/source/SkiaSharp.Views.Forms/SkiaSharp.Views.Forms.Native.Shared/SKCanvasViewRendererBase.cs old mode 100644 new mode 100755 index 74e5071f..2f86b5a3 --- a/source/SkiaSharp.Views.Forms/SkiaSharp.Views.Forms.Native.Shared/SKCanvasViewRendererBase.cs +++ b/source/SkiaSharp.Views.Forms/SkiaSharp.Views.Forms.Native.Shared/SKCanvasViewRendererBase.cs @@ -21,6 +21,11 @@ using SKNativePaintSurfaceEventArgs = SkiaSharp.Views.UWP.SKPaintSurfaceEventArg using Xamarin.Forms.Platform.MacOS; using SKNativeView = SkiaSharp.Views.Mac.SKCanvasView; using SKNativePaintSurfaceEventArgs = SkiaSharp.Views.Mac.SKPaintSurfaceEventArgs; +#elif TIZEN4_0 +using Xamarin.Forms.Platform.Tizen; +using SKNativeView = SkiaSharp.Views.Tizen.SKCanvasView; +using SKNativePaintSurfaceEventArgs = SkiaSharp.Views.Tizen.SKPaintSurfaceEventArgs; +using TForms = Xamarin.Forms.Platform.Tizen.Forms; #endif namespace SkiaSharp.Views.Forms @@ -65,6 +70,10 @@ namespace SkiaSharp.Views.Forms touchHandler = new SKTouchHandler( args => ((ISKCanvasViewController)Element).OnTouch(args), coord => Element.IgnorePixelScaling ? coord : (float)(coord * Control.Dpi)); +#elif TIZEN4_0 + touchHandler = new SKTouchHandler( + args => ((ISKCanvasViewController)Element).OnTouch(args), + coord => Element.IgnorePixelScaling ? Tizen.ScalingInfo.FromPixel(coord) : coord); #endif } @@ -118,6 +127,12 @@ namespace SkiaSharp.Views.Forms { return (TNativeView)Activator.CreateInstance(typeof(TNativeView), new[] { Context }); } +#elif TIZEN4_0 + protected virtual TNativeView CreateNativeControl() + { + TNativeView ret = (TNativeView)Activator.CreateInstance(typeof(TNativeView), new[] { TForms.Context.MainWindow }); + return ret; + } #else protected virtual TNativeView CreateNativeControl() { diff --git a/source/SkiaSharp.Views.Forms/SkiaSharp.Views.Forms.Native.Shared/SKGLViewRendererBase.cs b/source/SkiaSharp.Views.Forms/SkiaSharp.Views.Forms.Native.Shared/SKGLViewRendererBase.cs old mode 100644 new mode 100755 index b2d5e801..023e4dcb --- a/source/SkiaSharp.Views.Forms/SkiaSharp.Views.Forms.Native.Shared/SKGLViewRendererBase.cs +++ b/source/SkiaSharp.Views.Forms/SkiaSharp.Views.Forms.Native.Shared/SKGLViewRendererBase.cs @@ -21,6 +21,11 @@ using SKNativePaintGLSurfaceEventArgs = SkiaSharp.Views.UWP.SKPaintGLSurfaceEven using Xamarin.Forms.Platform.MacOS; using SKNativeView = SkiaSharp.Views.Mac.SKGLView; using SKNativePaintGLSurfaceEventArgs = SkiaSharp.Views.Mac.SKPaintGLSurfaceEventArgs; +#elif TIZEN4_0 +using Xamarin.Forms.Platform.Tizen; +using SKNativeView = SkiaSharp.Views.Tizen.SKGLSurfaceView; +using SKNativePaintGLSurfaceEventArgs = SkiaSharp.Views.Tizen.SKPaintGLSurfaceEventArgs; +using TForms = Xamarin.Forms.Platform.Tizen.Forms; #endif namespace SkiaSharp.Views.Forms @@ -65,6 +70,10 @@ namespace SkiaSharp.Views.Forms touchHandler = new SKTouchHandler( args => ((ISKGLViewController)Element).OnTouch(args), coord => (float)(coord * Control.ContentsScale)); +#elif TIZEN4_0 + touchHandler = new SKTouchHandler( + args => ((ISKGLViewController)Element).OnTouch(args), + coord => coord); #endif } @@ -124,6 +133,12 @@ namespace SkiaSharp.Views.Forms { return (TNativeView)Activator.CreateInstance(typeof(TNativeView), new[] { Context }); } +#elif TIZEN4_0 + protected virtual TNativeView CreateNativeControl() + { + TNativeView ret = (TNativeView)Activator.CreateInstance(typeof(TNativeView), new[] { TForms.Context.MainWindow }); + return ret; + } #else protected virtual TNativeView CreateNativeControl() { diff --git a/source/SkiaSharp.Views.Forms/SkiaSharp.Views.Forms.Tizen/SKCanvasViewRenderer.cs b/source/SkiaSharp.Views.Forms/SkiaSharp.Views.Forms.Tizen/SKCanvasViewRenderer.cs new file mode 100755 index 00000000..3aa52b22 --- /dev/null +++ b/source/SkiaSharp.Views.Forms/SkiaSharp.Views.Forms.Tizen/SKCanvasViewRenderer.cs @@ -0,0 +1,18 @@ +using Xamarin.Forms.Platform.Tizen; +using Xamarin.Forms; + +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, IRegisterable + { + public int ABC + { + get; + set; + } + } +} diff --git a/source/SkiaSharp.Views.Forms/SkiaSharp.Views.Forms.Tizen/SKGLViewRenderer.cs b/source/SkiaSharp.Views.Forms/SkiaSharp.Views.Forms.Tizen/SKGLViewRenderer.cs new file mode 100755 index 00000000..594d4d1a --- /dev/null +++ b/source/SkiaSharp.Views.Forms/SkiaSharp.Views.Forms.Tizen/SKGLViewRenderer.cs @@ -0,0 +1,22 @@ +using SkiaSharp.Views.Tizen; +using Xamarin.Forms.Platform.Tizen; + +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 + { + protected override void SetupRenderLoop(bool oneShot) + { + if (oneShot) + { + Control.Invalidate(); + } + + Control.RenderingMode = Element.HasRenderLoop ? RenderingMode.Continuously : RenderingMode.WhenDirty; + } + } +} diff --git a/source/SkiaSharp.Views.Forms/SkiaSharp.Views.Forms.Tizen/SKImageSourceHandler.cs b/source/SkiaSharp.Views.Forms/SkiaSharp.Views.Forms.Tizen/SKImageSourceHandler.cs new file mode 100755 index 00000000..bdef4e07 --- /dev/null +++ b/source/SkiaSharp.Views.Forms/SkiaSharp.Views.Forms.Tizen/SKImageSourceHandler.cs @@ -0,0 +1,67 @@ +using SkiaSharp.Views.Tizen; +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))] + +namespace SkiaSharp.Views.Forms +{ + public abstract class SKImageSourceHandler : IImageSourceHandler + { + private StreamImageSourceHandler handler = new StreamImageSourceHandler(); + + public Task LoadImageAsync(Xamarin.Forms.Platform.Tizen.Native.Image image, ImageSource imageSource, CancellationToken cancelationToken = default(CancellationToken)) + { + return handler.LoadImageAsync(image, ImageSource.FromStream(() => ToStream(imageSource)), cancelationToken); + } + + 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) + { + return pictureImageSource.Picture?.ToStream(pictureImageSource.Dimensions); + } + else + { + return null; + } + } + } +} diff --git a/source/SkiaSharp.Views.Forms/SkiaSharp.Views.Forms.Tizen/SKTouchHandler.cs b/source/SkiaSharp.Views.Forms/SkiaSharp.Views.Forms.Tizen/SKTouchHandler.cs new file mode 100755 index 00000000..a5d0326f --- /dev/null +++ b/source/SkiaSharp.Views.Forms/SkiaSharp.Views.Forms.Tizen/SKTouchHandler.cs @@ -0,0 +1,131 @@ +using System; +using ElmSharp; + +namespace SkiaSharp.Views.Forms +{ + internal class SKTouchHandler + { + private readonly MomentumHandler momentumHandler; + + private Action onTouchAction; + + private Func scalePixels; + + private GestureLayer gestureLayer; + + public SKTouchHandler(Action onTouchAction, Func scalePixels) + { + this.onTouchAction = onTouchAction; + this.scalePixels = scalePixels; + + momentumHandler = new MomentumHandler(this); + } + + public void SetEnabled(EvasObject view, bool enableTouchEvents) + { + if (view != null) + { + if (enableTouchEvents) + { + CreateGestureLayer(view); + } + else + { + DestroyGestureLayer(); + } + } + } + + public void Detach(EvasObject view) + { + // clean the view + SetEnabled(view, false); + + // remove references + onTouchAction = null; + scalePixels = null; + } + + private void CreateGestureLayer(EvasObject parent) + { + if (gestureLayer == null) + { + gestureLayer = new GestureLayer(parent); + gestureLayer.Attach(parent); + gestureLayer.Deleted += (s, e) => + { + gestureLayer = null; + DestroyGestureLayer(); + }; + gestureLayer.IsEnabled = true; + + AddMomentumGesture(); + } + } + + private void DestroyGestureLayer() + { + if (gestureLayer != null) + { + gestureLayer.IsEnabled = false; + gestureLayer.Unrealize(); + gestureLayer = null; + } + } + + private void AddMomentumGesture() + { + gestureLayer.SetMomentumCallback(GestureLayer.GestureState.Start, (data) => { momentumHandler.OnStarted(); }); + gestureLayer.SetMomentumCallback(GestureLayer.GestureState.Move, (data) => { momentumHandler.OnMoved(); }); + gestureLayer.SetMomentumCallback(GestureLayer.GestureState.End, (data) => { momentumHandler.OnFinished(); }); + gestureLayer.SetMomentumCallback(GestureLayer.GestureState.Abort, (data) => { momentumHandler.OnAborted(); }); + } + + private class MomentumHandler + { + private readonly SKTouchHandler handler; + + private int currentId = 0; + + public MomentumHandler(SKTouchHandler h) + { + handler = h; + } + + public void OnStarted() + { + ++currentId; + PostEvent(SKTouchAction.Pressed); + } + + public void OnMoved() + { + PostEvent(SKTouchAction.Moved); + } + + public void OnFinished() + { + PostEvent(SKTouchAction.Released); + } + + public void OnAborted() + { + PostEvent(SKTouchAction.Cancelled); + } + + 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)); + var inContact = (action == SKTouchAction.Pressed || action == SKTouchAction.Moved) ? true : false; + + handler.onTouchAction(new SKTouchEventArgs(currentId, action, coords, inContact)); + } + } + } +} diff --git a/source/SkiaSharp.Views.Forms/SkiaSharp.Views.Forms.Tizen/SkiaSharp.Views.Forms.Tizen.csproj b/source/SkiaSharp.Views.Forms/SkiaSharp.Views.Forms.Tizen/SkiaSharp.Views.Forms.Tizen.csproj new file mode 100755 index 00000000..7859bed2 --- /dev/null +++ b/source/SkiaSharp.Views.Forms/SkiaSharp.Views.Forms.Tizen/SkiaSharp.Views.Forms.Tizen.csproj @@ -0,0 +1,34 @@ + + + + + tizen40 + library + SkiaSharp.Views.Forms + SkiaSharp.Views.Forms + False + False + SkiaSharp.Views.Forms + tizen40 + + + TRACE;DEBUG + bin\Debug\ + + + TRACE + bin\Release\ + + + + + + + + + + + + + + diff --git a/source/SkiaSharp.Views/SkiaSharp.Views.Shared/Extensions.cs b/source/SkiaSharp.Views/SkiaSharp.Views.Shared/Extensions.cs old mode 100644 new mode 100755 index f33f5bad..0d05f8cd --- a/source/SkiaSharp.Views/SkiaSharp.Views.Shared/Extensions.cs +++ b/source/SkiaSharp.Views/SkiaSharp.Views.Shared/Extensions.cs @@ -13,6 +13,8 @@ namespace SkiaSharp.Views.Desktop namespace SkiaSharp.Views.UWP #elif __MACOS__ namespace SkiaSharp.Views.Mac +#elif TIZEN4_0 +namespace SkiaSharp.Views.Tizen #endif { public static class Extensions @@ -37,7 +39,7 @@ namespace SkiaSharp.Views.Mac internal static bool IsValidEnvironment => isValidEnvironment.Value; -#if !WINDOWS_UWP +#if !WINDOWS_UWP && !TIZEN4_0 // System.Drawing.Point* public static SKPoint ToSKPoint(this System.Drawing.PointF point) diff --git a/source/SkiaSharp.Views/SkiaSharp.Views.Shared/GlesInterop/Gles.cs b/source/SkiaSharp.Views/SkiaSharp.Views.Shared/GlesInterop/Gles.cs old mode 100644 new mode 100755 index fa2e61e9..684b6dcc --- a/source/SkiaSharp.Views/SkiaSharp.Views.Shared/GlesInterop/Gles.cs +++ b/source/SkiaSharp.Views/SkiaSharp.Views.Shared/GlesInterop/Gles.cs @@ -15,6 +15,8 @@ namespace SkiaSharp.Views.GlesInterop private const string libGLESv2 = "libGLESv2.so"; #elif WINDOWS_UWP private const string libGLESv2 = "libGLESv2.dll"; +#elif TIZEN4_0 + private const string libGLESv2 = "libGLESv2.so"; #endif public const int GL_FRAMEBUFFER_BINDING = 0x8CA6; diff --git a/source/SkiaSharp.Views/SkiaSharp.Views.Shared/SKGLDrawable.cs b/source/SkiaSharp.Views/SkiaSharp.Views.Shared/SKGLDrawable.cs old mode 100644 new mode 100755 index 33fa240a..eeb4a9f8 --- a/source/SkiaSharp.Views/SkiaSharp.Views.Shared/SKGLDrawable.cs +++ b/source/SkiaSharp.Views/SkiaSharp.Views.Shared/SKGLDrawable.cs @@ -14,6 +14,8 @@ namespace SkiaSharp.Views.Desktop namespace SkiaSharp.Views.Mac #elif WINDOWS_UWP namespace SkiaSharp.Views.UWP +#elif TIZEN4_0 +namespace SkiaSharp.Views.Tizen #endif { internal static class SKGLDrawable diff --git a/source/SkiaSharp.Views/SkiaSharp.Views.Shared/SKPaintGLSurfaceEventArgs.cs b/source/SkiaSharp.Views/SkiaSharp.Views.Shared/SKPaintGLSurfaceEventArgs.cs old mode 100644 new mode 100755 index 367dcad8..8e926db5 --- a/source/SkiaSharp.Views/SkiaSharp.Views.Shared/SKPaintGLSurfaceEventArgs.cs +++ b/source/SkiaSharp.Views/SkiaSharp.Views.Shared/SKPaintGLSurfaceEventArgs.cs @@ -13,6 +13,8 @@ namespace SkiaSharp.Views.Desktop namespace SkiaSharp.Views.UWP #elif __MACOS__ namespace SkiaSharp.Views.Mac +#elif TIZEN4_0 +namespace SkiaSharp.Views.Tizen #endif { public class SKPaintGLSurfaceEventArgs : EventArgs diff --git a/source/SkiaSharp.Views/SkiaSharp.Views.Shared/SKPaintSurfaceEventArgs.cs b/source/SkiaSharp.Views/SkiaSharp.Views.Shared/SKPaintSurfaceEventArgs.cs old mode 100644 new mode 100755 index f04080b4..ae787756 --- a/source/SkiaSharp.Views/SkiaSharp.Views.Shared/SKPaintSurfaceEventArgs.cs +++ b/source/SkiaSharp.Views/SkiaSharp.Views.Shared/SKPaintSurfaceEventArgs.cs @@ -14,6 +14,8 @@ namespace SkiaSharp.Views.Desktop namespace SkiaSharp.Views.UWP #elif __MACOS__ namespace SkiaSharp.Views.Mac +#elif TIZEN4_0 +namespace SkiaSharp.Views.Tizen #endif { public class SKPaintSurfaceEventArgs : EventArgs diff --git a/source/SkiaSharp.Views/SkiaSharp.Views.Tizen/CustomRenderingView.cs b/source/SkiaSharp.Views/SkiaSharp.Views.Tizen/CustomRenderingView.cs new file mode 100755 index 00000000..bc4efbf8 --- /dev/null +++ b/source/SkiaSharp.Views/SkiaSharp.Views.Tizen/CustomRenderingView.cs @@ -0,0 +1,280 @@ +using ElmSharp; +using System; + +namespace SkiaSharp.Views.Tizen +{ + /// + /// Widget which allows to implement custom rendering procedure. + /// + /// kkk + public abstract class CustomRenderingView : Widget + { + // called when image needs to be redrawn + private readonly Interop.Evas.Image.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; + + /// + /// Creates a new instance with the given object as its parent. + /// + /// The parent object. + public CustomRenderingView(EvasObject parent) : base(parent) + { + // initialize the callbacks + Resized += (sender, e) => OnResized(); + redrawCallback = (d, o) => OnDrawFrame(); + } + + /// + /// The size of the surface. + /// + public SKSize SurfaceSize => new SKSize(SurfaceWidth, SurfaceHeight); + + public SKSize CanvasSize => SurfaceSize; + + /// + /// Rendering mode used to control repainting the surface. + /// + /// + /// Default value is RenderingMode.WhenDirty. + /// + public RenderingMode RenderingMode + { + get + { + return renderingMode; + } + + set + { + if (renderingMode != value) + { + renderingMode = value; + + if (renderingMode == RenderingMode.Continuously) + { + CreateAnimator(); + } + else + { + DestroyAnimator(); + } + } + } + } + + /// + /// Width of the drawing surface. + /// + protected abstract int SurfaceWidth + { + get; + } + + /// + /// Height of the drawing surface. + /// + protected abstract int SurfaceHeight + { + get; + } + + /// + /// Displays the rendered content. + /// + protected IntPtr EvasImage + { + get; + private set; + } + + /// + /// Requests to repaint the surface. + /// + /// + /// Surface is repainted when RenderingMode is set to RenderingMode.WhenDirty, otherwise repainting is controlled by EFL. + /// + public void Invalidate() + { + if (RenderingMode == RenderingMode.WhenDirty) + { + Repaint(); + } + } + + /// + /// Creates the native resources which should be present throughout whole life of the control. + /// + /// The parent object. + /// + /// This method is empty. + /// + protected virtual void CreateNativeResources(EvasObject parent) + { + // empty on purpose + } + + /// + /// Destroys the native resources. + /// + /// + /// This method is empty. + /// + protected virtual void DestroyNativeResources() + { + // empty on purpose + } + + /// + /// Current frame should be drawn into the image. + /// + protected abstract void OnDrawFrame(); + + /// + /// Updates the drawing surface's size. + /// + /// Current geometry of the control. + /// true, if size has changed, false otherwise. + protected abstract bool UpdateSurfaceSize(Rect geometry); + + /// + /// Creates the drawing surface. + /// + /// + /// This method is empty. + /// + protected virtual void CreateDrawingSurface() + { + // empty on purpose + } + + /// + /// Destroys the drawing surface. + /// + /// + /// This method is empty. + /// + protected virtual void DestroyDrawingSurface() + { + // empty on purpose + } + + /// + /// Creates the EFL controls. + /// + /// The parent object. + /// Pointer to the newly created control. + protected sealed override IntPtr CreateHandle(EvasObject parent) + { + Console.WriteLine("SEC-CustomRenderingView.CreateHandle parent:" + parent); + IntPtr 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); + + Interop.Elementary.elm_object_part_content_set(handle, "elm.swallow.content", EvasImage); + + CreateNativeResources(parent); + Console.WriteLine("SEC-CustomRenderingView.CreateHandle handle:" + handle); + return handle; + } + + /// + /// Cleans up. + /// + protected sealed override void OnUnrealize() + { + DestroyAnimator(); + DestroyDrawingSurface(); + DestroyNativeResources(); + + base.OnUnrealize(); + } + + /// + /// Notifies that the size of the drawing surface has changed. + /// + protected void OnSurfaceSizeChanged() + { + OnResized(); + } + + private void OnResized() + { + var geometry = Geometry; + + if (geometry.Width <= 0 || geometry.Height <= 0) + { + // control is not yet fully initialized + return; + } + + if (UpdateSurfaceSize(geometry)) + { + RemoveImageCallback(); + + // recreate the drawing surface to match the new size + DestroyDrawingSurface(); + ResizeImage(); + CreateDrawingSurface(); + + SetImageCallback(); + + // 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(); + return true; + }); + } + } + + private void DestroyAnimator() + { + if (animator != IntPtr.Zero) + { + EcoreAnimator.RemoveAnimator(animator); + 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); + } + } +} diff --git a/source/SkiaSharp.Views/SkiaSharp.Views.Tizen/Interop/Interop.Elementary.Image.cs b/source/SkiaSharp.Views/SkiaSharp.Views.Tizen/Interop/Interop.Elementary.Image.cs new file mode 100755 index 00000000..155829b8 --- /dev/null +++ b/source/SkiaSharp.Views/SkiaSharp.Views.Tizen/Interop/Interop.Elementary.Image.cs @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +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); + } +} diff --git a/source/SkiaSharp.Views/SkiaSharp.Views.Tizen/Interop/Interop.Elementary.cs b/source/SkiaSharp.Views/SkiaSharp.Views.Tizen/Interop/Interop.Elementary.cs new file mode 100755 index 00000000..ea01b939 --- /dev/null +++ b/source/SkiaSharp.Views/SkiaSharp.Views.Tizen/Interop/Interop.Elementary.cs @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System; +using System.Runtime.InteropServices; + +internal static partial class Interop +{ + internal static partial class Elementary + { + [DllImport(Libraries.Elementary)] + internal static extern IntPtr elm_layout_add(IntPtr obj); + + [DllImport(Libraries.Elementary)] + internal static extern bool elm_layout_theme_set(IntPtr obj, string klass, string group, string style); + + [DllImport(Libraries.Elementary)] + internal static extern IntPtr elm_object_part_content_get(IntPtr obj, string part); + + [DllImport(Libraries.Elementary)] + internal static extern void elm_object_part_content_set(IntPtr obj, string part, IntPtr content); + } +} diff --git a/source/SkiaSharp.Views/SkiaSharp.Views.Tizen/Interop/Interop.Evas.GL.Api.cs b/source/SkiaSharp.Views/SkiaSharp.Views.Tizen/Interop/Interop.Evas.GL.Api.cs new file mode 100755 index 00000000..da058911 --- /dev/null +++ b/source/SkiaSharp.Views/SkiaSharp.Views.Tizen/Interop/Interop.Evas.GL.Api.cs @@ -0,0 +1,734 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System; +using System.Reflection; +using System.Runtime.InteropServices; + +internal static partial class Interop +{ + internal static partial class Evas + { + internal static partial class GL + { + internal interface IApi + { + IntPtr GetFunctionPointer(string name); + } + + internal class ApiWrapper : IApi + { + private IntPtr glEvas; + + private Api api; + + private glViewport viewport; + + private glClear clear; + + public ApiWrapper(IntPtr evas_gl) + { + glEvas = evas_gl; + + var unmanagedGlApi = evas_gl_api_get(glEvas); + api = Marshal.PtrToStructure(unmanagedGlApi); + + viewport = GetDelegate(); + clear = GetDelegate(); + } + + public IntPtr GetFunctionPointer(string name) + { + var ret = evas_gl_proc_address_get(glEvas, name); + + if (ret == IntPtr.Zero) + { + ret = api.GetFunctionPointer(name); + } + + return ret; + } + + public void GlViewport(int x, int y, int width, int height) + { + viewport(x, y, width, height); + } + + public void GlClear(uint mask) + { + clear(mask); + } + + private T GetDelegate() + { + return Marshal.GetDelegateForFunctionPointer(GetFunctionPointer(typeof(T).Name)); + } + + private delegate void glViewport(int x, int y, int width, int height); + private delegate void glClear(uint mask); + } + + internal struct Api : IApi + { + // this structure is initialized from a native pointer +#pragma warning disable 0169 + // DO NOT change the order, needs to be as specified in struct _Evas_GL_API (/platform/upstream/efl/src/lib/evas/Evas_GL.h) + // DO NOT change the names, they need to match the OpenGL API + private int version; + private IntPtr glActiveTexture; + private IntPtr glAttachShader; + private IntPtr glBindAttribLocation; + private IntPtr glBindBuffer; + private IntPtr glBindFramebuffer; + private IntPtr glBindRenderbuffer; + private IntPtr glBindTexture; + private IntPtr glBlendColor; + private IntPtr glBlendEquation; + private IntPtr glBlendEquationSeparate; + private IntPtr glBlendFunc; + private IntPtr glBlendFuncSeparate; + private IntPtr glBufferData; + private IntPtr glBufferSubData; + private IntPtr glCheckFramebufferStatus; + private IntPtr glClear; + private IntPtr glClearColor; + private IntPtr glClearDepthf; + private IntPtr glClearStencil; + private IntPtr glColorMask; + private IntPtr glCompileShader; + private IntPtr glCompressedTexImage2D; + private IntPtr glCompressedTexSubImage2D; + private IntPtr glCopyTexImage2D; + private IntPtr glCopyTexSubImage2D; + private IntPtr glCreateProgram; + private IntPtr glCreateShader; + private IntPtr glCullFace; + private IntPtr glDeleteBuffers; + private IntPtr glDeleteFramebuffers; + private IntPtr glDeleteProgram; + private IntPtr glDeleteRenderbuffers; + private IntPtr glDeleteShader; + private IntPtr glDeleteTextures; + private IntPtr glDepthFunc; + private IntPtr glDepthMask; + private IntPtr glDepthRangef; + private IntPtr glDetachShader; + private IntPtr glDisable; + private IntPtr glDisableVertexAttribArray; + private IntPtr glDrawArrays; + private IntPtr glDrawElements; + private IntPtr glEnable; + private IntPtr glEnableVertexAttribArray; + private IntPtr glFinish; + private IntPtr glFlush; + private IntPtr glFramebufferRenderbuffer; + private IntPtr glFramebufferTexture2D; + private IntPtr glFrontFace; + private IntPtr glGenBuffers; + private IntPtr glGenerateMipmap; + private IntPtr glGenFramebuffers; + private IntPtr glGenRenderbuffers; + private IntPtr glGenTextures; + private IntPtr glGetActiveAttrib; + private IntPtr glGetActiveUniform; + private IntPtr glGetAttachedShaders; + private IntPtr glGetAttribLocation; + private IntPtr glGetBooleanv; + private IntPtr glGetBufferParameteriv; + private IntPtr glGetError; + private IntPtr glGetFloatv; + private IntPtr glGetFramebufferAttachmentParameteriv; + private IntPtr glGetIntegerv; + private IntPtr glGetProgramiv; + private IntPtr glGetProgramInfoLog; + private IntPtr glGetRenderbufferParameteriv; + private IntPtr glGetShaderiv; + private IntPtr glGetShaderInfoLog; + private IntPtr glGetShaderPrecisionFormat; + private IntPtr glGetShaderSource; + private IntPtr glGetString; + private IntPtr glGetTexParameterfv; + private IntPtr glGetTexParameteriv; + private IntPtr glGetUniformfv; + private IntPtr glGetUniformiv; + private IntPtr glGetUniformLocation; + private IntPtr glGetVertexAttribfv; + private IntPtr glGetVertexAttribiv; + private IntPtr glGetVertexAttribPointerv; + private IntPtr glHint; + private IntPtr glIsBuffer; + private IntPtr glIsEnabled; + private IntPtr glIsFramebuffer; + private IntPtr glIsProgram; + private IntPtr glIsRenderbuffer; + private IntPtr glIsShader; + private IntPtr glIsTexture; + private IntPtr glLineWidth; + private IntPtr glLinkProgram; + private IntPtr glPixelStorei; + private IntPtr glPolygonOffset; + private IntPtr glReadPixels; + private IntPtr glReleaseShaderCompiler; + private IntPtr glRenderbufferStorage; + private IntPtr glSampleCoverage; + private IntPtr glScissor; + private IntPtr glShaderBinary; + private IntPtr glShaderSource; + private IntPtr glStencilFunc; + private IntPtr glStencilFuncSeparate; + private IntPtr glStencilMask; + private IntPtr glStencilMaskSeparate; + private IntPtr glStencilOp; + private IntPtr glStencilOpSeparate; + private IntPtr glTexImage2D; + private IntPtr glTexParameterf; + private IntPtr glTexParameterfv; + private IntPtr glTexParameteri; + private IntPtr glTexParameteriv; + private IntPtr glTexSubImage2D; + private IntPtr glUniform1f; + private IntPtr glUniform1fv; + private IntPtr glUniform1i; + private IntPtr glUniform1iv; + private IntPtr glUniform2f; + private IntPtr glUniform2fv; + private IntPtr glUniform2i; + private IntPtr glUniform2iv; + private IntPtr glUniform3f; + private IntPtr glUniform3fv; + private IntPtr glUniform3i; + private IntPtr glUniform3iv; + private IntPtr glUniform4f; + private IntPtr glUniform4fv; + private IntPtr glUniform4i; + private IntPtr glUniform4iv; + private IntPtr glUniformMatrix2fv; + private IntPtr glUniformMatrix3fv; + private IntPtr glUniformMatrix4fv; + private IntPtr glUseProgram; + private IntPtr glValidateProgram; + private IntPtr glVertexAttrib1f; + private IntPtr glVertexAttrib1fv; + private IntPtr glVertexAttrib2f; + private IntPtr glVertexAttrib2fv; + private IntPtr glVertexAttrib3f; + private IntPtr glVertexAttrib3fv; + private IntPtr glVertexAttrib4f; + private IntPtr glVertexAttrib4fv; + private IntPtr glVertexAttribPointer; + private IntPtr glViewport; + private IntPtr glEvasGLImageTargetTexture2DOES; + private IntPtr glEvasGLImageTargetRenderbufferStorageOES; + private IntPtr glGetProgramBinaryOES; + private IntPtr glProgramBinaryOES; + private IntPtr glMapBufferOES; + private IntPtr glUnmapBufferOES; + private IntPtr glGetBufferPointervOES; + private IntPtr glTexImage3DOES; + private IntPtr glTexSubImage3DOES; + private IntPtr glCopyTexSubImage3DOES; + private IntPtr glCompressedTexImage3DOES; + private IntPtr glCompressedTexSubImage3DOES; + private IntPtr glFramebufferTexture3DOES; + private IntPtr glGetPerfMonitorGroupsAMD; + private IntPtr glGetPerfMonitorCountersAMD; + private IntPtr glGetPerfMonitorGroupStringAMD; + private IntPtr glGetPerfMonitorCounterStringAMD; + private IntPtr glGetPerfMonitorCounterInfoAMD; + private IntPtr glGenPerfMonitorsAMD; + private IntPtr glDeletePerfMonitorsAMD; + private IntPtr glSelectPerfMonitorCountersAMD; + private IntPtr glBeginPerfMonitorAMD; + private IntPtr glEndPerfMonitorAMD; + private IntPtr glGetPerfMonitorCounterDataAMD; + private IntPtr glDiscardFramebufferEXT; + private IntPtr glMultiDrawArraysEXT; + private IntPtr glMultiDrawElementsEXT; + private IntPtr glDeleteFencesNV; + private IntPtr glGenFencesNV; + private IntPtr glIsFenceNV; + private IntPtr glTestFenceNV; + private IntPtr glGetFenceivNV; + private IntPtr glFinishFenceNV; + private IntPtr glSetFenceNV; + private IntPtr glGetDriverControlsQCOM; + private IntPtr glGetDriverControlStringQCOM; + private IntPtr glEnableDriverControlQCOM; + private IntPtr glDisableDriverControlQCOM; + private IntPtr glExtGetTexturesQCOM; + private IntPtr glExtGetBuffersQCOM; + private IntPtr glExtGetRenderbuffersQCOM; + private IntPtr glExtGetFramebuffersQCOM; + private IntPtr glExtGetTexLevelParameterivQCOM; + private IntPtr glExtTexObjectStateOverrideiQCOM; + private IntPtr glExtGetTexSubImageQCOM; + private IntPtr glExtGetBufferPointervQCOM; + private IntPtr glExtGetShadersQCOM; + private IntPtr glExtGetProgramsQCOM; + private IntPtr glExtIsProgramBinaryQCOM; + private IntPtr glExtGetProgramBinarySourceQCOM; + private IntPtr evasglCreateImage; + private IntPtr evasglDestroyImage; + private IntPtr evasglCreateImageForContext; + private IntPtr glAlphaFunc; + private IntPtr glClipPlanef; + private IntPtr glColor4f; + private IntPtr glFogf; + private IntPtr glFogfv; + private IntPtr glFrustumf; + private IntPtr glGetClipPlanef; + private IntPtr glGetLightfv; + private IntPtr glGetMaterialfv; + private IntPtr glGetTexEnvfv; + private IntPtr glLightModelf; + private IntPtr glLightModelfv; + private IntPtr glLightf; + private IntPtr glLightfv; + private IntPtr glLoadMatrixf; + private IntPtr glMaterialf; + private IntPtr glMaterialfv; + private IntPtr glMultMatrixf; + private IntPtr glMultiTexCoord4f; + private IntPtr glNormal3f; + private IntPtr glOrthof; + private IntPtr glPointParameterf; + private IntPtr glPointParameterfv; + private IntPtr glPointSize; + private IntPtr glPointSizePointerOES; + private IntPtr glRotatef; + private IntPtr glScalef; + private IntPtr glTexEnvf; + private IntPtr glTexEnvfv; + private IntPtr glTranslatef; + private IntPtr glAlphaFuncx; + private IntPtr glClearColorx; + private IntPtr glClearDepthx; + private IntPtr glClientActiveTexture; + private IntPtr glClipPlanex; + private IntPtr glColor4ub; + private IntPtr glColor4x; + private IntPtr glColorPointer; + private IntPtr glDepthRangex; + private IntPtr glDisableClientState; + private IntPtr glEnableClientState; + private IntPtr glFogx; + private IntPtr glFogxv; + private IntPtr glFrustumx; + private IntPtr glGetClipPlanex; + private IntPtr glGetFixedv; + private IntPtr glGetLightxv; + private IntPtr glGetMaterialxv; + private IntPtr glGetPointerv; + private IntPtr glGetTexEnviv; + private IntPtr glGetTexEnvxv; + private IntPtr glGetTexParameterxv; + private IntPtr glLightModelx; + private IntPtr glLightModelxv; + private IntPtr glLightx; + private IntPtr glLightxv; + private IntPtr glLineWidthx; + private IntPtr glLoadIdentity; + private IntPtr glLoadMatrixx; + private IntPtr glLogicOp; + private IntPtr glMaterialx; + private IntPtr glMaterialxv; + private IntPtr glMatrixMode; + private IntPtr glMultMatrixx; + private IntPtr glMultiTexCoord4x; + private IntPtr glNormal3x; + private IntPtr glNormalPointer; + private IntPtr glOrthox; + private IntPtr glPointParameterx; + private IntPtr glPointParameterxv; + private IntPtr glPointSizex; + private IntPtr glPolygonOffsetx; + private IntPtr glPopMatrix; + private IntPtr glPushMatrix; + private IntPtr glRotatex; + private IntPtr glSampleCoveragex; + private IntPtr glScalex; + private IntPtr glShadeModel; + private IntPtr glTexCoordPointer; + private IntPtr glTexEnvi; + private IntPtr glTexEnvx; + private IntPtr glTexEnviv; + private IntPtr glTexEnvxv; + private IntPtr glTexParameterx; + private IntPtr glTexParameterxv; + private IntPtr glTranslatex; + private IntPtr glVertexPointer; + private IntPtr glBlendEquationSeparateOES; + private IntPtr glBlendFuncSeparateOES; + private IntPtr glBlendEquationOES; + private IntPtr glDrawTexsOES; + private IntPtr glDrawTexiOES; + private IntPtr glDrawTexxOES; + private IntPtr glDrawTexsvOES; + private IntPtr glDrawTexivOES; + private IntPtr glDrawTexxvOES; + private IntPtr glDrawTexfOES; + private IntPtr glDrawTexfvOES; + private IntPtr glAlphaFuncxOES; + private IntPtr glClearColorxOES; + private IntPtr glClearDepthxOES; + private IntPtr glClipPlanexOES; + private IntPtr glColor4xOES; + private IntPtr glDepthRangexOES; + private IntPtr glFogxOES; + private IntPtr glFogxvOES; + private IntPtr glFrustumxOES; + private IntPtr glGetClipPlanexOES; + private IntPtr glGetFixedvOES; + private IntPtr glGetLightxvOES; + private IntPtr glGetMaterialxvOES; + private IntPtr glGetTexEnvxvOES; + private IntPtr glGetTexParameterxvOES; + private IntPtr glLightModelxOES; + private IntPtr glLightModelxvOES; + private IntPtr glLightxOES; + private IntPtr glLightxvOES; + private IntPtr glLineWidthxOES; + private IntPtr glLoadMatrixxOES; + private IntPtr glMaterialxOES; + private IntPtr glMaterialxvOES; + private IntPtr glMultMatrixxOES; + private IntPtr glMultiTexCoord4xOES; + private IntPtr glNormal3xOES; + private IntPtr glOrthoxOES; + private IntPtr glPointParameterxOES; + private IntPtr glPointParameterxvOES; + private IntPtr glPointSizexOES; + private IntPtr glPolygonOffsetxOES; + private IntPtr glRotatexOES; + private IntPtr glSampleCoveragexOES; + private IntPtr glScalexOES; + private IntPtr glTexEnvxOES; + private IntPtr glTexEnvxvOES; + private IntPtr glTexParameterxOES; + private IntPtr glTexParameterxvOES; + private IntPtr glTranslatexOES; + private IntPtr glIsRenderbufferOES; + private IntPtr glBindRenderbufferOES; + private IntPtr glDeleteRenderbuffersOES; + private IntPtr glGenRenderbuffersOES; + private IntPtr glRenderbufferStorageOES; + private IntPtr glGetRenderbufferParameterivOES; + private IntPtr glIsFramebufferOES; + private IntPtr glBindFramebufferOES; + private IntPtr glDeleteFramebuffersOES; + private IntPtr glGenFramebuffersOES; + private IntPtr glCheckFramebufferStatusOES; + private IntPtr glFramebufferRenderbufferOES; + private IntPtr glFramebufferTexture2DOES; + private IntPtr glGetFramebufferAttachmentParameterivOES; + private IntPtr glGenerateMipmapOES; + private IntPtr glCurrentPaletteMatrixOES; + private IntPtr glLoadPaletteFromModelViewMatrixOES; + private IntPtr glMatrixIndexPointerOES; + private IntPtr glWeightPointerOES; + private IntPtr glQueryMatrixxOES; + private IntPtr glDepthRangefOES; + private IntPtr glFrustumfOES; + private IntPtr glOrthofOES; + private IntPtr glClipPlanefOES; + private IntPtr glGetClipPlanefOES; + private IntPtr glClearDepthfOES; + private IntPtr glTexGenfOES; + private IntPtr glTexGenfvOES; + private IntPtr glTexGeniOES; + private IntPtr glTexGenivOES; + private IntPtr glTexGenxOES; + private IntPtr glTexGenxvOES; + private IntPtr glGetTexGenfvOES; + private IntPtr glGetTexGenivOES; + private IntPtr glGetTexGenxvOES; + private IntPtr glBindVertexArrayOES; + private IntPtr glDeleteVertexArraysOES; + private IntPtr glGenVertexArraysOES; + private IntPtr glIsVertexArrayOES; + private IntPtr glCopyTextureLevelsAPPLE; + private IntPtr glRenderbufferStorageMultisampleAPPLE; + private IntPtr glResolveMultisampleFramebufferAPPLE; + private IntPtr glFenceSyncAPPLE; + private IntPtr glIsSyncAPPLE; + private IntPtr glDeleteSyncAPPLE; + private IntPtr glClientWaitSyncAPPLE; + private IntPtr glWaitSyncAPPLE; + private IntPtr glGetInteger64vAPPLE; + private IntPtr glGetSyncivAPPLE; + private IntPtr glMapBufferRangeEXT; + private IntPtr glFlushMappedBufferRangeEXT; + private IntPtr glRenderbufferStorageMultisampleEXT; + private IntPtr glFramebufferTexture2DMultisampleEXT; + private IntPtr glGetGraphicsResetStatusEXT; + private IntPtr glReadnPixelsEXT; + private IntPtr glGetnUniformfvEXT; + private IntPtr glGetnUniformivEXT; + private IntPtr glTexStorage1DEXT; + private IntPtr glTexStorage2DEXT; + private IntPtr glTexStorage3DEXT; + private IntPtr glTextureStorage1DEXT; + private IntPtr glTextureStorage2DEXT; + private IntPtr glTextureStorage3DEXT; + private IntPtr glClipPlanefIMG; + private IntPtr glClipPlanexIMG; + private IntPtr glRenderbufferStorageMultisampleIMG; + private IntPtr glFramebufferTexture2DMultisampleIMG; + private IntPtr glStartTilingQCOM; + private IntPtr glEndTilingQCOM; + private IntPtr evasglCreateSync; + private IntPtr evasglDestroySync; + private IntPtr evasglClientWaitSync; + private IntPtr evasglSignalSync; + private IntPtr evasglGetSyncAttrib; + private IntPtr evasglWaitSync; + private IntPtr evasglBindWaylandDisplay; + private IntPtr evasglUnbindWaylandDisplay; + private IntPtr evasglQueryWaylandBuffer; + private IntPtr glBeginQuery; + private IntPtr glBeginTransformFeedback; + private IntPtr glBindBufferBase; + private IntPtr glBindBufferRange; + private IntPtr glBindSampler; + private IntPtr glBindTransformFeedback; + private IntPtr glBindVertexArray; + private IntPtr glBlitFramebuffer; + private IntPtr glClearBufferfi; + private IntPtr glClearBufferfv; + private IntPtr glClearBufferiv; + private IntPtr glClearBufferuiv; + private IntPtr glClientWaitSync; + private IntPtr glCompressedTexImage3D; + private IntPtr glCompressedTexSubImage3D; + private IntPtr glCopyBufferSubData; + private IntPtr glCopyTexSubImage3D; + private IntPtr glDeleteQueries; + private IntPtr glDeleteSamplers; + private IntPtr glDeleteSync; + private IntPtr glDeleteTransformFeedbacks; + private IntPtr glDeleteVertexArrays; + private IntPtr glDrawArraysInstanced; + private IntPtr glDrawBuffers; + private IntPtr glDrawElementsInstanced; + private IntPtr glDrawRangeElements; + private IntPtr glEndQuery; + private IntPtr glEndTransformFeedback; + private IntPtr glFenceSync; + private IntPtr glFlushMappedBufferRange; + private IntPtr glFramebufferTextureLayer; + private IntPtr glGenQueries; + private IntPtr glGenSamplers; + private IntPtr glGenTransformFeedbacks; + private IntPtr glGenVertexArrays; + private IntPtr glGetActiveUniformBlockiv; + private IntPtr glGetActiveUniformBlockName; + private IntPtr glGetActiveUniformsiv; + private IntPtr glGetBufferParameteri64v; + private IntPtr glGetBufferPointerv; + private IntPtr glGetFragDataLocation; + private IntPtr glGetInteger64i_v; + private IntPtr glGetInteger64v; + private IntPtr glGetIntegeri_v; + private IntPtr glGetInternalformativ; + private IntPtr glGetProgramBinary; + private IntPtr glGetQueryiv; + private IntPtr glGetQueryObjectuiv; + private IntPtr glGetSamplerParameterfv; + private IntPtr glGetSamplerParameteriv; + private IntPtr glGetStringi; + private IntPtr glGetSynciv; + private IntPtr glGetTransformFeedbackVarying; + private IntPtr glGetUniformBlockIndex; + private IntPtr glGetUniformIndices; + private IntPtr glGetUniformuiv; + private IntPtr glGetVertexAttribIiv; + private IntPtr glGetVertexAttribIuiv; + private IntPtr glInvalidateFramebuffer; + private IntPtr glInvalidateSubFramebuffer; + private IntPtr glIsQuery; + private IntPtr glIsSampler; + private IntPtr glIsSync; + private IntPtr glIsTransformFeedback; + private IntPtr glIsVertexArray; + private IntPtr glMapBufferRange; + private IntPtr glPauseTransformFeedback; + private IntPtr glProgramBinary; + private IntPtr glProgramParameteri; + private IntPtr glReadBuffer; + private IntPtr glRenderbufferStorageMultisample; + private IntPtr glResumeTransformFeedback; + private IntPtr glSamplerParameterf; + private IntPtr glSamplerParameterfv; + private IntPtr glSamplerParameteri; + private IntPtr glSamplerParameteriv; + private IntPtr glTexImage3D; + private IntPtr glTexStorage2D; + private IntPtr glTexStorage3D; + private IntPtr glTexSubImage3D; + private IntPtr glTransformFeedbackVaryings; + private IntPtr glUniform1ui; + private IntPtr glUniform1uiv; + private IntPtr glUniform2ui; + private IntPtr glUniform2uiv; + private IntPtr glUniform3ui; + private IntPtr glUniform3uiv; + private IntPtr glUniform4ui; + private IntPtr glUniform4uiv; + private IntPtr glUniformBlockBinding; + private IntPtr glUniformMatrix2x3fv; + private IntPtr glUniformMatrix3x2fv; + private IntPtr glUniformMatrix2x4fv; + private IntPtr glUniformMatrix4x2fv; + private IntPtr glUniformMatrix3x4fv; + private IntPtr glUniformMatrix4x3fv; + private IntPtr glUnmapBuffer; + private IntPtr glVertexAttribDivisor; + private IntPtr glVertexAttribI4i; + private IntPtr glVertexAttribI4iv; + private IntPtr glVertexAttribI4ui; + private IntPtr glVertexAttribI4uiv; + private IntPtr glVertexAttribIPointer; + private IntPtr glWaitSync; + private IntPtr glDispatchCompute; + private IntPtr glDispatchComputeIndirect; + private IntPtr glDrawArraysIndirect; + private IntPtr glDrawElementsIndirect; + private IntPtr glFramebufferParameteri; + private IntPtr glGetFramebufferParameteriv; + private IntPtr glGetProgramInterfaceiv; + private IntPtr glGetProgramResourceIndex; + private IntPtr glGetProgramResourceName; + private IntPtr glGetProgramResourceiv; + private IntPtr glGetProgramResourceLocation; + private IntPtr glUseProgramStages; + private IntPtr glActiveShaderProgram; + private IntPtr glCreateShaderProgramv; + private IntPtr glBindProgramPipeline; + private IntPtr glDeleteProgramPipelines; + private IntPtr glGenProgramPipelines; + private IntPtr glIsProgramPipeline; + private IntPtr glGetProgramPipelineiv; + private IntPtr glProgramUniform1i; + private IntPtr glProgramUniform2i; + private IntPtr glProgramUniform3i; + private IntPtr glProgramUniform4i; + private IntPtr glProgramUniform1ui; + private IntPtr glProgramUniform2ui; + private IntPtr glProgramUniform3ui; + private IntPtr glProgramUniform4ui; + private IntPtr glProgramUniform1f; + private IntPtr glProgramUniform2f; + private IntPtr glProgramUniform3f; + private IntPtr glProgramUniform4f; + private IntPtr glProgramUniform1iv; + private IntPtr glProgramUniform2iv; + private IntPtr glProgramUniform3iv; + private IntPtr glProgramUniform4iv; + private IntPtr glProgramUniform1uiv; + private IntPtr glProgramUniform2uiv; + private IntPtr glProgramUniform3uiv; + private IntPtr glProgramUniform4uiv; + private IntPtr glProgramUniform1fv; + private IntPtr glProgramUniform2fv; + private IntPtr glProgramUniform3fv; + private IntPtr glProgramUniform4fv; + private IntPtr glProgramUniformMatrix2fv; + private IntPtr glProgramUniformMatrix3fv; + private IntPtr glProgramUniformMatrix4fv; + private IntPtr glProgramUniformMatrix2x3fv; + private IntPtr glProgramUniformMatrix3x2fv; + private IntPtr glProgramUniformMatrix2x4fv; + private IntPtr glProgramUniformMatrix4x2fv; + private IntPtr glProgramUniformMatrix3x4fv; + private IntPtr glProgramUniformMatrix4x3fv; + private IntPtr glValidateProgramPipeline; + private IntPtr glGetProgramPipelineInfoLog; + private IntPtr glBindImageTexture; + private IntPtr glGetBooleani_v; + private IntPtr glMemoryBarrier; + private IntPtr glMemoryBarrierByRegion; + private IntPtr glTexStorage2DMultisample; + private IntPtr glGetMultisamplefv; + private IntPtr glSampleMaski; + private IntPtr glGetTexLevelParameteriv; + private IntPtr glGetTexLevelParameterfv; + private IntPtr glBindVertexBuffer; + private IntPtr glVertexAttribFormat; + private IntPtr glVertexAttribIFormat; + private IntPtr glVertexAttribBinding; + private IntPtr glVertexBindingDivisor; + private IntPtr glBlendBarrier; + private IntPtr glCopyImageSubData; + private IntPtr glDebugMessageControl; + private IntPtr glDebugMessageInsert; + private IntPtr glDebugMessageCallback; + private IntPtr glGetDebugMessageLog; + private IntPtr glPushDebugGroup; + private IntPtr glPopDebugGroup; + private IntPtr glObjectLabel; + private IntPtr glGetObjectLabel; + private IntPtr glObjectPtrLabel; + private IntPtr glGetObjectPtrLabel; + private IntPtr glEnablei; + private IntPtr glDisablei; + private IntPtr glBlendEquationi; + private IntPtr glBlendEquationSeparatei; + private IntPtr glBlendFunci; + private IntPtr glBlendFuncSeparatei; + private IntPtr glColorMaski; + private IntPtr glIsEnabledi; + private IntPtr glDrawElementsBaseVertex; + private IntPtr glDrawRangeElementsBaseVertex; + private IntPtr glDrawElementsInstancedBaseVertex; + private IntPtr glFramebufferTexture; + private IntPtr glPrimitiveBoundingBox; + private IntPtr glGetGraphicsResetStatus; + private IntPtr glReadnPixels; + private IntPtr glGetnUniformfv; + private IntPtr glGetnUniformiv; + private IntPtr glGetnUniformuiv; + private IntPtr glMinSampleShading; + private IntPtr glPatchParameteri; + private IntPtr glTexParameterIiv; + private IntPtr glTexParameterIuiv; + private IntPtr glGetTexParameterIiv; + private IntPtr glGetTexParameterIuiv; + private IntPtr glSamplerParameterIiv; + private IntPtr glSamplerParameterIuiv; + private IntPtr glGetSamplerParameterIiv; + private IntPtr glGetSamplerParameterIuiv; + private IntPtr glTexBuffer; + private IntPtr glTexBufferRange; + private IntPtr glTexStorage3DMultisample; +#pragma warning restore 0169 + + public IntPtr GetFunctionPointer(string name) + { + var field = GetType().GetField(name, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); + + if (field != null && field.FieldType == typeof(IntPtr)) + { + return (IntPtr)field.GetValue(this); + } + else + { + return IntPtr.Zero; + } + } + } + } + } +} diff --git a/source/SkiaSharp.Views/SkiaSharp.Views.Tizen/Interop/Interop.Evas.GL.cs b/source/SkiaSharp.Views/SkiaSharp.Views.Tizen/Interop/Interop.Evas.GL.cs new file mode 100755 index 00000000..774b1929 --- /dev/null +++ b/source/SkiaSharp.Views/SkiaSharp.Views.Tizen/Interop/Interop.Evas.GL.cs @@ -0,0 +1,246 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +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 + { + /// + /// Surface Color Format + /// + public ColorFormat color_format; + /// + /// Surface Depth Bits + /// + public DepthBits depth_bits; + /// + /// Surface Stencil Bits + /// + public StencilBits stencil_bits; + /// + /// Extra Surface Options + /// + public OptionsBits options_bits; + /// + /// Optional Surface MSAA Bits + /// + public MultisampleBits multisample_bits; +#pragma warning disable 0169 + /// + /// @internal Special flag for OpenGL-ES 1.1 indirect rendering surfaces + /// + /// + /// Not used. + /// + 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 + /// + /// OpenGL texture id to use from glGenTextures(). + /// + uint texture_id; + /// + /// 0 if not a FBO, FBO id otherwise from glGenFramebuffers(). + /// + uint framebuffer_id; + /// + /// Same as 'internalFormat' for glTexImage2D(). + /// + uint internal_format; + /// + /// Same as 'format' for glTexImage2D(). + /// + uint format; + /// + /// 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). + /// + uint x; + uint y; + uint w; + uint h; +#pragma warning restore 0169 + } + + internal enum ColorFormat + { + /// + /// Opaque RGB surface + /// + RGB_888 = 0, + /// + /// RGBA surface with alpha + /// + RGBA_8888 = 1, + /// + /// Special value for creating PBuffer surfaces without any attached buffer. + /// + NO_FBO = 2 + } + + internal enum DepthBits + { + NONE = 0, + /// + /// 8 bits precision surface depth + /// + BIT_8 = 1, + /// + /// 16 bits precision surface depth + /// + BIT_16 = 2, + /// + /// 24 bits precision surface depth + /// + BIT_24 = 3, + /// + /// 32 bits precision surface depth + /// + BIT_32 = 4 + } + + internal enum StencilBits + { + NONE = 0, + /// + /// 1 bit precision for stencil buffer + /// + BIT_1 = 1, + /// + /// 2 bits precision for stencil buffer + /// + BIT_2 = 2, + /// + /// 4 bits precision for stencil buffer + /// + BIT_4 = 3, + /// + /// 8 bits precision for stencil buffer + /// + BIT_8 = 4, + /// + /// 16 bits precision for stencil buffer + /// + BIT_16 = 5 + } + + internal enum OptionsBits + { + /// + /// No extra options. + /// + NONE = 0, + /// + /// Optional hint to allow rendering directly to the Evas window if possible. + /// + DIRECT = (1 << 0), + /// + /// Force direct rendering even if the canvas is rotated. + /// + CLIENT_SIDE_ROTATION = (1 << 1), + /// + /// If enabled, Evas GL pixel callback will be called by another thread instead of main thread. + /// + THREAD = (1 << 2) + } + + internal enum MultisampleBits + { + /// + /// No multisample rendering. + /// + NONE = 0, + /// + /// MSAA with minimum number of samples. + /// + LOW = 1, + /// + /// MSAA with half the maximum number of samples. + /// + MED = 2, + /// + /// MSAA with maximum allowed samples. + /// + HIGH = 3 + } + + internal enum ContextVersion + { + /// + /// OpenGL-ES 1.x + /// + GLES_1_X = 1, + /// + /// OpenGL-ES 2.x is the default + /// + GLES_2_X = 2, + /// + /// OpenGL-ES 3.x (@b Since 2.4) + /// + GLES_3_X = 3, + /// + /// Enable debug mode on this context (See GL_KHR_debug) (@b Since 4.0) + /// + DEBUG = 0x1000 + } + } + } +} diff --git a/source/SkiaSharp.Views/SkiaSharp.Views.Tizen/Interop/Interop.Evas.Image.cs b/source/SkiaSharp.Views/SkiaSharp.Views.Tizen/Interop/Interop.Evas.Image.cs new file mode 100755 index 00000000..07793591 --- /dev/null +++ b/source/SkiaSharp.Views/SkiaSharp.Views.Tizen/Interop/Interop.Evas.Image.cs @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +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, + } + } + } +} diff --git a/source/SkiaSharp.Views/SkiaSharp.Views.Tizen/Interop/Interop.Evas.cs b/source/SkiaSharp.Views/SkiaSharp.Views.Tizen/Interop/Interop.Evas.cs new file mode 100755 index 00000000..e83715c3 --- /dev/null +++ b/source/SkiaSharp.Views/SkiaSharp.Views.Tizen/Interop/Interop.Evas.cs @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +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); + } +} diff --git a/source/SkiaSharp.Views/SkiaSharp.Views.Tizen/Interop/Interop.Libaries.cs b/source/SkiaSharp.Views/SkiaSharp.Views.Tizen/Interop/Interop.Libaries.cs new file mode 100755 index 00000000..bd19df0c --- /dev/null +++ b/source/SkiaSharp.Views/SkiaSharp.Views.Tizen/Interop/Interop.Libaries.cs @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +internal static partial class Interop +{ + private static class Libraries + { + internal const string Libc = "libc.so.6"; + internal const string Evas = "libevas.so.1"; + internal const string Elementary = "libelementary.so.1"; + internal const string Eina = "libeina.so.1"; + internal const string Ecore = "libecore.so.1"; + internal const string Eo = "libeo.so.1"; + internal const string Eext = "libefl-extension.so.0"; + } +} diff --git a/source/SkiaSharp.Views/SkiaSharp.Views.Tizen/RenderingMode.cs b/source/SkiaSharp.Views/SkiaSharp.Views.Tizen/RenderingMode.cs new file mode 100755 index 00000000..71432d7e --- /dev/null +++ b/source/SkiaSharp.Views/SkiaSharp.Views.Tizen/RenderingMode.cs @@ -0,0 +1,17 @@ +namespace SkiaSharp.Views.Tizen +{ + /// + /// Rendering mode used by the CustomRenderingView. + /// + public enum RenderingMode + { + /// + /// View decides when to repaint the surface. + /// + Continuously, + /// + /// Surface is repainted on demand. + /// + WhenDirty, + } +} diff --git a/source/SkiaSharp.Views/SkiaSharp.Views.Tizen/SKCanvasView.cs b/source/SkiaSharp.Views/SkiaSharp.Views.Tizen/SKCanvasView.cs new file mode 100755 index 00000000..e13bebf5 --- /dev/null +++ b/source/SkiaSharp.Views/SkiaSharp.Views.Tizen/SKCanvasView.cs @@ -0,0 +1,94 @@ +using ElmSharp; +using System; + +namespace SkiaSharp.Views.Tizen +{ + /// + /// Software rendering for Skia. + /// + public class SKCanvasView : CustomRenderingView + { + /// + /// Backing field for IgnorePixelScaling. + /// + private bool ignorePixelScaling; + + /// + /// Information about the surface. + /// + private SKImageInfo info = new SKImageInfo(0, 0, SKImageInfo.PlatformColorType, SKAlphaType.Premul); + + /// + /// Creates new instance with the given object as its parent. + /// + /// The parent object. + public SKCanvasView(EvasObject parent) : base(parent) + { + } + + /// + /// 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. + /// + /// + /// Default value is false. + /// + public bool IgnorePixelScaling + { + get + { + return ignorePixelScaling; + } + + set + { + if (ignorePixelScaling != value) + { + ignorePixelScaling = value; + OnSurfaceSizeChanged(); + } + } + } + + public event EventHandler PaintSurface; + + protected sealed override int SurfaceWidth => info.Width; + + protected sealed override int SurfaceHeight => info.Height; + + protected virtual void OnDrawFrame(SKSurface surface, SKImageInfo info) + { + PaintSurface?.Invoke(this, new SKPaintSurfaceEventArgs(surface, info)); + } + + 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)) + { + // draw using SkiaSharp + OnDrawFrame(surface, info); + surface.Canvas.Flush(); + } + } + + protected sealed override bool UpdateSurfaceSize(Rect geometry) + { + var w = info.Width; + var h = info.Height; + + if (IgnorePixelScaling) + { + info.Width = (int)ScalingInfo.FromPixel(geometry.Width); + info.Height = (int)ScalingInfo.FromPixel(geometry.Height); + } + else + { + info.Width = geometry.Width; + info.Height = geometry.Height; + } + + return (w != info.Width || h != info.Height); + } + } +} diff --git a/source/SkiaSharp.Views/SkiaSharp.Views.Tizen/SKGLSurfaceView.cs b/source/SkiaSharp.Views/SkiaSharp.Views.Tizen/SKGLSurfaceView.cs new file mode 100755 index 00000000..8d33885d --- /dev/null +++ b/source/SkiaSharp.Views/SkiaSharp.Views.Tizen/SKGLSurfaceView.cs @@ -0,0 +1,268 @@ +using ElmSharp; +using System; +using System.Runtime.InteropServices; + +namespace SkiaSharp.Views.Tizen +{ + /// + /// OpenGL surface for Skia. + /// + 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, + }; + + // pointer to glConfig passed to the native side + private IntPtr unmanagedGlConfig; + + // connects the EFL with OpenGL + private IntPtr glEvas; + + // drawing context + private IntPtr glContext; + + // access to OpenGL API + private Interop.Evas.GL.ApiWrapper glApi; + + // EFL wrapper for a OpenGL surface + private IntPtr glSurface; + + // Skia-related members + private GRContext context; + + private GRBackendRenderTargetDesc renderTarget = new GRBackendRenderTargetDesc + { + Config = GRPixelConfig.Unknown, + Origin = GRSurfaceOrigin.TopLeft, + }; + + /// + /// Creates new instance with the given object as its parent. + /// + /// The parent object. + public SKGLSurfaceView(EvasObject parent) : base(parent) + { + } + + public event EventHandler PaintSurface; + + public GRContext GRContext => context; + + protected sealed override int SurfaceWidth => renderTarget.Width; + + protected sealed override int SurfaceHeight => renderTarget.Height; + + /// + /// Performs the drawing to the specified surface. + /// + /// Surface to draw to. + /// Description of the rendering context. + protected virtual void OnDrawFrame(SKSurface surface, GRBackendRenderTargetDesc renderTarget) + { + PaintSurface?.Invoke(this, new SKPaintGLSurfaceEventArgs(surface, renderTarget)); + } + + protected sealed override void CreateNativeResources(EvasObject parent) + { + CreateGL(parent); + } + + protected sealed override void DestroyNativeResources() + { + DestroyGL(); + } + + protected sealed override void OnDrawFrame() + { + if (glSurface != IntPtr.Zero) + { + glApi.GlClear(GlesInterop.Gles.GL_STENCIL_BUFFER_BIT); + + // create the surface + using (var surface = SKSurface.Create(context, renderTarget)) + { + // draw using SkiaSharp + OnDrawFrame(surface, renderTarget); + + surface.Canvas.Flush(); + } + + // flush the SkiaSharp contents to GL + context.Flush(); + } + } + + protected sealed override bool UpdateSurfaceSize(Rect geometry) + { + if (geometry.Width != renderTarget.Width || geometry.Height != renderTarget.Height) + { + // size has changed, update geometry + renderTarget.Width = geometry.Width; + renderTarget.Height = geometry.Height; + + return true; + } + else + { + return false; + } + } + + protected sealed override void CreateDrawingSurface() + { + CreateSurface(); + } + + protected sealed override void DestroyDrawingSurface() + { + DestroySurface(); + } + + private void CreateGL(EvasObject parent) + { + if (glEvas == IntPtr.Zero) + { + // initialize the OpenGL (the EFL way) + glEvas = Interop.Evas.GL.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); + + // initialize the context + glContext = Interop.Evas.GL.evas_gl_context_create(glEvas, IntPtr.Zero); + + // obtain the OpenGL function pointers + glApi = new Interop.Evas.GL.ApiWrapper(glEvas); + } + } + + private void DestroyGL() + { + if (glEvas != IntPtr.Zero) + { + // zero the instance + glApi = null; + + // destroy the context + Interop.Evas.GL.evas_gl_context_destroy(glEvas, glContext); + glContext = IntPtr.Zero; + + // release the unmanaged memory + Marshal.FreeHGlobal(unmanagedGlConfig); + unmanagedGlConfig = IntPtr.Zero; + + // destroy the EFL wrapper + Interop.Evas.GL.evas_gl_free(glEvas); + glEvas = IntPtr.Zero; + } + } + + private void CreateSurface() + { + if (glSurface == IntPtr.Zero) + { + // create the surface + glSurface = Interop.Evas.GL.evas_gl_surface_create(glEvas, unmanagedGlConfig, 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); + + // switch to the current OpenGL context + Interop.Evas.GL.evas_gl_make_current(glEvas, glSurface, glContext); + + // resize the viewport + glApi.GlViewport(0, 0, renderTarget.Width, renderTarget.Height); + + // initialize the Skia's context + CreateContext(); + FillRenderTarget(); + } + } + + private void DestroySurface() + { + if (glSurface != IntPtr.Zero) + { + // finalize the Skia's context + DestroyContext(); + + // disconnect the surface from the image + Interop.Evas.Image.evas_object_image_native_surface_set(EvasImage, IntPtr.Zero); + + // destroy the surface + Interop.Evas.GL.evas_gl_surface_destroy(glEvas, glSurface); + glSurface = IntPtr.Zero; + } + } + + private void CreateContext() + { + // create the interface using the function pointers provided by the EFL + var glInterface = GRGlInterface.AssembleInterface((c, n) => glApi.GetFunctionPointer(n)); + context = GRContext.Create(GRBackend.OpenGL, glInterface); + } + + private void DestroyContext() + { + if (context != null) + { + // dispose the unmanaged memory + context.Dispose(); + 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"); + } + } + } +} diff --git a/source/SkiaSharp.Views/SkiaSharp.Views.Tizen/ScalingInfo.cs b/source/SkiaSharp.Views/SkiaSharp.Views.Tizen/ScalingInfo.cs new file mode 100755 index 00000000..5990acb3 --- /dev/null +++ b/source/SkiaSharp.Views/SkiaSharp.Views.Tizen/ScalingInfo.cs @@ -0,0 +1,54 @@ +using ElmSharp; +using System; + +using TSystemInfo = Tizen.System.SystemInfo; + +namespace SkiaSharp.Views.Tizen +{ + public static class ScalingInfo + { + private static Lazy s_profile = new Lazy(() => + { + return Elementary.GetProfile(); + }); + + /// + /// DPI of the screen. + /// + private static Lazy s_dpi = new Lazy(() => + { + Console.WriteLine("SEC--ScalingInfo Profile : " + Profile); + if (Profile == "tv") + { + // TV has fixed DPI value (72) + return 72; + } + + int dpi = 0; + TSystemInfo.TryGetValue("http://tizen.org/feature/screen.dpi", out dpi); + Console.WriteLine("SEC--ScalingInfo DPI : " + dpi); + return dpi; + }); + + /// + /// Scaling factor, allows to convert pixels to Android-style device-independent pixels. + /// + private static Lazy s_scalingFactor = new Lazy(() => s_dpi.Value / 160.0f); + + public static string Profile => s_profile.Value; + + public static int DPI => s_dpi.Value; + + public static float ScalingFactor => s_scalingFactor.Value; + + public static float FromPixel(float v) + { + return v / ScalingFactor; + } + + public static float ToPixel(float v) + { + return v * ScalingFactor; + } + } +} diff --git a/source/SkiaSharp.Views/SkiaSharp.Views.Tizen/SkiaSharp.Views.Tizen.csproj b/source/SkiaSharp.Views/SkiaSharp.Views.Tizen/SkiaSharp.Views.Tizen.csproj new file mode 100755 index 00000000..68c56b22 --- /dev/null +++ b/source/SkiaSharp.Views/SkiaSharp.Views.Tizen/SkiaSharp.Views.Tizen.csproj @@ -0,0 +1,36 @@ + + + + + tizen40 + library + SkiaSharp.Views.Tizen + SkiaSharp.Views.Tizen + False + False + true + true + ..\..\..\mono.snk + SkiaSharp.Views + tizen40 + + + TRACE;DEBUG + bin\Debug\ + + + TRACE + bin\Release\ + + + + + + + + + + + + + diff --git a/source/SkiaSharp.Views/SkiaSharp.Views.Tizen/TizenExtensions.cs b/source/SkiaSharp.Views/SkiaSharp.Views.Tizen/TizenExtensions.cs new file mode 100755 index 00000000..c6a85c83 --- /dev/null +++ b/source/SkiaSharp.Views/SkiaSharp.Views.Tizen/TizenExtensions.cs @@ -0,0 +1,83 @@ +using ElmSharp; +using System; +using System.IO; + +namespace SkiaSharp.Views.Tizen +{ + public static class TizenExtensions + { + // Point* + public static SKPoint ToSKPoint(this Point point) + { + return new SKPoint(point.X, point.Y); + } + + public static SKPointI ToSKPointI(this Point point) + { + return new SKPointI(point.X, point.Y); + } + + public static Point ToPoint(this SKPoint point) + { + 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 }; + } + + // Rectangle* + public static SKRect ToSKRect(this Rect rect) + { + return new SKRect(rect.Left, rect.Top, rect.Right, rect.Bottom); + } + + public static SKRectI ToSKRectI(this Rect rect) + { + return new SKRectI(rect.Left, rect.Top, rect.Right, rect.Bottom); + } + + public static Rect ToRect(this SKRect rect) + { + return new Rect((int)rect.Left, (int)rect.Top, (int)rect.Right, (int)rect.Bottom); + } + + public static Rect ToRect(this SKRectI rect) + { + return new Rect(rect.Left, rect.Top, rect.Right, rect.Bottom); + } + + // Color + public static SKColor ToSKColor(this Color color) + { + return new SKColor((byte)color.R, (byte)color.G, (byte)color.B, (byte)color.A); + } + + public static Color ToColor(this SKColor color) + { + 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)); + } + } +} diff --git a/source/SkiaSharpSource.Linux.sln b/source/SkiaSharpSource.Linux.sln old mode 100644 new mode 100755 index 5ec10a0a..49f314bb --- a/source/SkiaSharpSource.Linux.sln +++ b/source/SkiaSharpSource.Linux.sln @@ -47,6 +47,14 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HarfBuzzSharp.NetStandard", EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SkiaSharp.NetStandard", "..\binding\SkiaSharp.NetStandard\SkiaSharp.NetStandard.csproj", "{CCAE7E65-9040-400F-B5BF-941A0279643E}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SkiaSharp.Views.Tizen", "SkiaSharp.Views\SkiaSharp.Views.Tizen\SkiaSharp.Views.Tizen.csproj", "{BBFA4E90-48A6-4B2B-9111-517FB47F76FA}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SkiaSharp.Views.Forms.Tizen", "SkiaSharp.Views.Forms\SkiaSharp.Views.Forms.Tizen\SkiaSharp.Views.Forms.Tizen.csproj", "{857CB6E9-BA27-4E94-A2D7-58BFF1EE193A}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SkiaSharp.Tizen", "..\binding\SkiaSharp.Tizen\SkiaSharp.Tizen.csproj", "{6ADD085E-75AC-4924-AC54-798B2FA1C697}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HarfBuzzSharp.Tizen", "..\binding\HarfBuzzSharp.Tizen\HarfBuzzSharp.Tizen.csproj", "{DE587D56-A4EC-43F8-BA34-7EB811FC35D0}" +EndProject Global GlobalSection(SharedMSBuildProjectFiles) = preSolution SkiaSharp.Views.Forms\SkiaSharp.Views.Forms.Shared\SkiaSharp.Views.Forms.Shared.projitems*{1555d119-8598-4e4d-91ac-d313f94a1673}*SharedItemsImports = 4 @@ -105,6 +113,22 @@ Global {CCAE7E65-9040-400F-B5BF-941A0279643E}.Debug|Any CPU.Build.0 = Debug|Any CPU {CCAE7E65-9040-400F-B5BF-941A0279643E}.Release|Any CPU.ActiveCfg = Release|Any CPU {CCAE7E65-9040-400F-B5BF-941A0279643E}.Release|Any CPU.Build.0 = Release|Any CPU + {BBFA4E90-48A6-4B2B-9111-517FB47F76FA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BBFA4E90-48A6-4B2B-9111-517FB47F76FA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BBFA4E90-48A6-4B2B-9111-517FB47F76FA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BBFA4E90-48A6-4B2B-9111-517FB47F76FA}.Release|Any CPU.Build.0 = Release|Any CPU + {857CB6E9-BA27-4E94-A2D7-58BFF1EE193A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {857CB6E9-BA27-4E94-A2D7-58BFF1EE193A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {857CB6E9-BA27-4E94-A2D7-58BFF1EE193A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {857CB6E9-BA27-4E94-A2D7-58BFF1EE193A}.Release|Any CPU.Build.0 = Release|Any CPU + {6ADD085E-75AC-4924-AC54-798B2FA1C697}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6ADD085E-75AC-4924-AC54-798B2FA1C697}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6ADD085E-75AC-4924-AC54-798B2FA1C697}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6ADD085E-75AC-4924-AC54-798B2FA1C697}.Release|Any CPU.Build.0 = Release|Any CPU + {DE587D56-A4EC-43F8-BA34-7EB811FC35D0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DE587D56-A4EC-43F8-BA34-7EB811FC35D0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DE587D56-A4EC-43F8-BA34-7EB811FC35D0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DE587D56-A4EC-43F8-BA34-7EB811FC35D0}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -126,6 +150,10 @@ Global {CEBD25FD-DD4F-4D5F-B809-D50D02176F41} = {B3C4E4EC-68C7-4AFB-A6D4-1B2B0EB8C421} {249C9EBD-88ED-4BE8-8EF7-72FB65659363} = {815C2429-8C88-4C09-B6AB-A916040F9FEF} {CCAE7E65-9040-400F-B5BF-941A0279643E} = {C335869B-7CC8-4239-B4A5-8031AA9758D3} + {BBFA4E90-48A6-4B2B-9111-517FB47F76FA} = {4F5EBFFB-DD81-43B9-8531-156ED3639C91} + {857CB6E9-BA27-4E94-A2D7-58BFF1EE193A} = {B3C4E4EC-68C7-4AFB-A6D4-1B2B0EB8C421} + {6ADD085E-75AC-4924-AC54-798B2FA1C697} = {C335869B-7CC8-4239-B4A5-8031AA9758D3} + {DE587D56-A4EC-43F8-BA34-7EB811FC35D0} = {815C2429-8C88-4C09-B6AB-A916040F9FEF} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {B4229170-607D-4886-9990-8FD5D86220B9}