Jump to content


  • Content Count

  • Joined

  • Last visited

  • Days Won


vfbb last won the day on May 29

vfbb had the most liked content!

Community Reputation

211 Excellent


Technical Information

  • Delphi-Version
    Delphi 11 Alexandria

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. That's why I made a topic warning that Weak is not thread safe (confirmed by @Dalija Prasnikar). So cast Weak to strong reference, and even if the strong reference is not nil, it can represent a destroyed object, generating a totally random AV, and this is not documented anywhere on the internet. More information: https://en.delphipraxis.net/topic/4020-weak-reference-is-dangerous/?tab=comments#comment-34379
  2. @3delite Loading dynamic libraries on Android is not that trivial, you will still have problems on some devices of some manufacturers. Here are 3 main tips: 1) Filename: ALWAYS suffix "lib", like "libbass.so" 2) Deployment: On 32bit, the remote path "library\lib\armeabi-v7a\" On 64bit, the remote path "library\lib\arm64-v8a\" Also on 64bit, add the 32bit binary with the remote path "library\lib\armeabi-v7a\" and the condition "'$(AndroidAppBundle)''==''true'" (with the quotes). The condition you can only change via ToolsApi or manually in .dproj. See how we do it: https://github.com/skia4delphi/skia4delphi/blob/eed4afbf8a34137a9bfa308bcb5ef87cee84abcb/Source/VCL/Designtime/Skia.Vcl.Designtime.ProjectMenu.pas#L219-L221 3) Loading: First try to load using only the filename, and in case of failure use the library path + filename. See how we do it: https://github.com/skia4delphi/skia4delphi/blob/eed4afbf8a34137a9bfa308bcb5ef87cee84abcb/Source/Skia.API.pas#L2119-L2124
  3. vfbb

    Performance monitor for FMX macOS?

    Moving away from the profile issue and talking specifically about the CPU usage of FMX on macOS, the same can be related to the use or not of metal. I advise using GlobalUseMetal := True; to take some of the CPU load off.
  4. vfbb

    Rounded polygon

    Here's an example: uses Skia; function MakeCubicSplineInterpolation(const APoints: TArray<TPointF>): ISkPath; var LPathBuilder: ISkPathBuilder; LSegments: Integer; I: Integer; mx: Single; my: Single; LScratches: array of record a, b, c, r, p: TPointF; end; begin LPathBuilder := TSkPathBuilder.Create; if Length(APoints) < 2 then Exit(LPathBuilder.Detach); if Length(APoints) = 2 then begin LPathBuilder.MoveTo(APoints[0]); LPathBuilder.LineTo(APoints[1]); Exit(LPathBuilder.Detach); end; LSegments := Length(APoints) - 1; SetLength(LScratches, LSegments); LScratches[0].a := PointF(0, 0); LScratches[0].b := PointF(2, 2); LScratches[0].c := PointF(1, 1); LScratches[0].r := PointF(APoints[0].X + 2 * APoints[1].X, APoints[0].Y + 2 * APoints[1].Y); for I := 1 to LSegments - 2 do begin LScratches[I].a := PointF(1, 1); LScratches[I].b := PointF(4, 4); LScratches[I].c := PointF(1, 1); LScratches[I].r := PointF(4 * APoints[i].X + 2 * APoints[I + 1].X, 4 * APoints[I].Y + 2 * APoints[I + 1].Y); end; LScratches[LSegments - 1].a := PointF(2, 2); LScratches[LSegments - 1].b := PointF(7, 7); LScratches[LSegments - 1].c := PointF(0, 0); LScratches[LSegments - 1].r := PointF(8 * APoints[LSegments - 1].X + APoints[LSegments].X, 8 * APoints[LSegments - 1].Y + APoints[LSegments].Y); for I := 1 to LSegments - 1 do begin mx := LScratches[I].a.X / LScratches[I - 1].b.X; my := LScratches[I].a.Y / LScratches[I - 1].b.Y; LScratches[I].b := LScratches[I].b - PointF(mx * LScratches[I - 1].c.X, my * LScratches[I - 1].c.Y); LScratches[I].r := LScratches[I].r - PointF(mx * LScratches[I - 1].r.X, my * LScratches[I - 1].r.Y); end; LScratches[LSegments - 1].p := PointF(LScratches[LSegments - 1].r.X / LScratches[LSegments - 1].b.X, LScratches[LSegments - 1].r.Y / LScratches[LSegments - 1].b.Y); for I := Length(APoints) - 3 downto 0 do begin LScratches[I].p := PointF((LScratches[I].r.X - LScratches[I].c.X * LScratches[I + 1].p.X) / LScratches[I].b.X, (LScratches[I].r.Y - LScratches[I].c.Y * LScratches[I + 1].p.Y) / LScratches[I].b.Y); end; LPathBuilder.MoveTo(APoints[0]); for I := 0 to LSegments - 2 do begin LPathBuilder.CubicTo(LScratches[I].p, PointF(2 * APoints[I + 1].X - LScratches[I + 1].p.X, 2 * APoints[I + 1].Y - LScratches[I + 1].p.Y), APoints[I + 1]); end; LPathBuilder.CubicTo(LScratches[LSegments - 1].p, PointF(0.5 * (APoints[LSegments].X + LScratches[LSegments - 1].p.X), 0.5 * (APoints[LSegments].Y + LScratches[LSegments - 1].p.Y)), APoints[LSegments]); Result := LPathBuilder.Detach; end; procedure TForm1.SkPaintBox1Draw(ASender: TObject; const ACanvas: ISkCanvas; const ADest: TRectF; const AOpacity: Single); var LPaint: ISkPaint; LMyPoints: TArray<TPointF>; begin LMyPoints := [PointF(62, 511), PointF(162, 605), PointF(262, 610), PointF(362, 402), PointF(462, 959), PointF(562, 58), PointF(662, 272), PointF(762, 99), PointF(862, 759), PointF(962, 945)]; LPaint := TSkPaint.Create(TSkPaintStyle.Stroke); LPaint.Color := TAlphaColors.Red; LPaint.AntiAlias := True; LPaint.StrokeWidth := 3; LPaint.StrokeCap := TSkStrokeCap.Round; ACanvas.DrawPath(MakeCubicSplineInterpolation(LMyPoints), LPaint); LPaint.StrokeWidth := 10; LPaint.Color := TAlphaColors.Black; ACanvas.DrawPoints(TSkDrawPointsMode.Points, LMyPoints, LPaint); end; Result: Note: You don't need to use Skia, it was just a facilitator for the example.
  5. vfbb

    Rounded polygon

    If you don't mind third-party solutions, Skia has an effect that applies rounded edges automatically and works for Console, Vcl and FMX: https://github.com/skia4delphi/skia4delphi/blob/eed4afbf8a34137a9bfa308bcb5ef87cee84abcb/Samples/Demo/FMX/Source/Sample.Form.PathsAndEffects.pas#L193 Result:
  6. We started porting the Skia4Delphi library to C++Builder and we came across a problem in the static linking of objects, specifically linking the file “/usr/lib/clang/lib/darwin/libclang_rt.ios.a” which is in the SDK path (ex: “C:\Users\<username>\Documents\Embarcadero\Studio\SDKs\iPhoneOS15.2.sdk\usr\lib\clang\lib\darwin\libclang_rt.ios.a”) In Delphi, this linking is very simple to do. We can simply declare a fake method and add the external '/<sdk_sub_path>/<filename>.a', which is exactly what we do in our Delphi implementation: procedure libcompiler_rt; external '/usr/lib/clang/lib/darwin/libclang_rt.ios.a'; In C++Builder however, we didn't find anything similar. So far we've only been able to force this link in two different (but very rudimentary) ways: Method 1 - Configuring project linking: Adding to the project library path “$(BDSPLATFORMSDKSDIR)\<DefaultPlatformSDK>\usr\lib\clang\lib\darwin\” Note: This is necessary because although some SDK paths are automatically passed to the linker, this is not. Adding the command -lclang_rt.ios to the project link The problem with this method is that apparently there is no environment variable for the <DefaultPlatformSDK>, and adding only relative paths, in this case “\usr\lib\clang\lib\darwin\”, doesn't work. We also tried “$(SDKROOT)\usr\lib\clang\lib\darwin\” but to no avail. Method 2 – Adding objects to the project Directly add the file “libclang_rt.ios.a” to the project. It also works, but this is also a bad option. Questions Is there any other way to force link an SDK object in C++Builder? It would be nice to have a simple solution that requires no configuration: #pragma link "/usr/lib/clang/lib/darwin/libclang_rt.ios.a" // But this don't work Would there be any variables we could use to represent the path of the SDK being used? (Ex: “$(SDKROOT)\usr\lib\clang\lib\darwin\”)
  7. vfbb

    Change splash_image_def.xml by default

    This can be avoided by simply disabling it from the project deployment and creating yours with the same remotedir and remotename. Whenever possible, it's better to do this in your project than in the default delphi files, because you won't be able to share your project with someone else without them having the same issue unless they also edit their default splash . Here's a practical example of a project that does this: https://github.com/skia4delphi/skia4delphi/tree/main/Samples/Webinar - Demo/FMX
  8. Make a cool demo using Skia4Delphi and Delphi 11.1 Alexandria, post it on GitHub, be the envy of all your friends, and maybe win a new M1 Mac Mini! Visit the official contest page: Skia4Delphi GUI Beauty Contest See also the latest Skia4Delphi webinar: Supercharge Your User Interface with Skia4Delphi - Webinar Replay - YouTube
  9. vfbb

    ANN: Skia4Delphi v3.4.0

    Can you send me your lottie file? Official skia documentation is incomplete, but it helps. The official skia api is very similar to Skia4Delphi, just few methods and functions have been renamed for readability. I imagine you want to know more about custom shaders. They are made in SKSL language, using the SkRuntimeEffect class to build the shader. See some useful links below: SKSL doc: https://skia.org/docs/user/sksl/ SKSL playground: https://shaders.skia.org/ SkiaSimpleShaderViewer - Demo using custom shaders in skia4delphi: https://github.com/jimmckeeth/SkiaSimpleShaderViewer BricksGame - Game using custom shaders in skia4delphi: https://github.com/skia4delphi/skia4delphi/tree/main/Samples/Webinar - Game/FMX Skia4Delphi Demo using custom shaders in two units: https://github.com/skia4delphi/skia4delphi/blob/main/Samples/Demo/FMX/Source/Sample.Form.RuntimeEffects.pas https://github.com/skia4delphi/skia4delphi/blob/main/Samples/Demo/FMX/Source/Sample.Form.Filter.pas There is also new documentation from the android team, which is AGSL section. Android Graphics Shader Language (AGSL) is Skia Shader Language (SKSL), the android team just changed the name: https://developer.android.com/guide/topics/graphics/agsl You can also solve all your doubts on our telegram channel: https://t.me/skia4delphi
  10. vfbb

    ANN: Skia4Delphi v3.4.0

    AE covers all kinds of animation, there are effects and raster features, for example, that would not even make sense to be supported in lottie, because the idea of lottie is to be vectorized and lightweight. Lastly, lottie and the bodymovin plugin are constantly developing and adding new features every day, so blogs from 1 year ago may no longer reflect reality.
  11. vfbb

    ANN: Skia4Delphi v3.4.0

    There are several limitations of Adobe After Effects to lottie (using bodymovin plugin) and they are not very well documented. This site lists some: https://www.elpassion.com/blog/lottie-who-common-mistakes-in-after-effects-animation-for-lottie Your case may have something to do with Keyframe or expressions...
  12. vfbb

    ANN: Skia4Delphi v3.4.0

    No truly interactive animations. But you could create these iterations artificially. Consider this example: https://lottiefiles.com/5222-switch between progress 0% to 50% is the animation enabling a switch, and progress 50% to 100% is the animation disabling a switch. Based on that you can configure the animation in your control so that when you click it execute the progress from 0% to 50% or from 50% to 100%. Note: Currently our TSkAnimatedImage control is capable of running lottie animations but it is not "so tunable". Either it automatically runs the entire animation or you activate the manual mode and change the progress on your own (for example by adding a timer and changing the progress manually every 15 ms). In our next release (in a few weeks) we will improve this a lot, we will add new properties to get better control of the animations in the TSkAnimatedImage control. Yes it is possible with Skia4Delphi. Excluding experimental or deprecated modules, 99% of the library is exposed.
  13. vfbb

    ANN: Skia4Delphi v3.4.0

    Skia does not support animated SVG. There are very few libs that support SVG animations and even then I believe there are no versions for delphi. However, there is something similar, and much better: lottie. Lottie are also vectorized animations in json format. As with SVG, you can also find lottie of everything on the internet. You can also create your own animation using Adobe After Effects (although it's hard for programmers lol). However it is not possible to edit it at runtime. Note: Replacing your app's canvas (GlobalUseSkia := True) is optional. You'll be able to use svg, lottie, skia controls, even without skia being your app's renderer. However, skia controls perform better when your app's canvas is based on skia (GlobalUseSkia := True)
  14. vfbb

    ANN: Skia4Delphi v3.4.0

    There are 2 questions in your test: 1) On the Windows platform, both the FMX and Skia canvas present very similar results, both in terms of quality and performance. Although on my machine there was a 10% gain, some reported the opposite, but overall both were satisfactory in all tests. On non-Windows platforms, the performance differences are greater and a second problem arises, which is the quality of the drawings (there is only antialiasing on FMX Windows, while on Skia there is maximum quality on all platforms); 2) In our canvas implementation, bitmaps are not as optimized as they could be. We split our canvas into 2 parts, the window canvas (form) and the bitmap canvas. In the implementation of the canvas bitmap we always decided to use the raster mode because we wanted the TBitmap to be used in background threads without locking the UI (embarcadero put a lock on the canvas that blocks drawings in parallel, even if you use bitmaps in threads, the drawings are not actually done in parallel, one blocks the other during BeginScene and EndScene). In our tests this raster implementation of bitmaps didn't affect the performance of projects that don't abuse bitmaps as much (but it's not your case, you're drawing 300 bitmaps at once);
  15. vfbb

    ANN: Skia4Delphi v3.4.0

    Yes. When you set "GlobalUseSkia := True;", the lib replaces the app's default canvas to the skia-based canvas. However, we made more than 1 canvas based on skia: a raster canvas (CPU), an opengl canvas (GPU) and a metal canvas (GPU). When creating the first form or drawing with bitmaps (which is when the FMX canvas system is started), we check if GlobalUseSkia is true, and if it is, we will choose one of our implementations based on the booleans GlobalUseSkiaRasterWhenAvailable and GlobalUseMetal, and on the target platform. But why use by default on Windows a raster canvas (which runs on the CPU), since the canvases that run on the GPU are faster? This was done because it is the most compatible mode of all, as some specific VMs do not implement full openGL support and often this is not possible to verify via code. In the future we intend to add new canvas implementations based on skia, such as the Vulkan implementation. Perhaps Vulkan was better implemented on Windows VMs.