-
Content Count
787 -
Joined
-
Last visited
-
Days Won
42
Posts posted by pyscripter
-
-
30 minutes ago, Kas Ob. said:OK, i giving up on this.
Thanks for your efforts...
-
2 minutes ago, Attila Kovacs said:As I first mentioned the in the AV reading address 0x00000001, the "1" is the parameter D2D1_SVG_ATTRIBUTE_POD_TYPE_COLOR.
Impressive guess work!
-
19 minutes ago, Mahdi Safsafi said:I believe you're wrong on $78 ! its for an overloaded GetAttributeValue function (not SetAttributeValue). So your code is calling an overloaded version of GetAttributeValue instead of SetAttributeValue.
Thanks, but this is puzzling. at $7C is the GetAttributeValue, which I know it works and at $78 should be the one before. (right?). In the include file the function before the GetAttributeValue is the relevant SetAttributeValue. How can I find the correct order?
-
15 minutes ago, Attila Kovacs said:looks like I'm being ignored here.
change the order of the last 2 SetAttributeValue()'s in the interface, no AV but I can't see any changes, maybe you would know why and see if it helps.
Wow. I was using the order in the include file. What exactly is the order that works? Could you please post the relevant section of the file or the file as a whole?
-
6 minutes ago, Kas Ob. said:Thank you for sharing the sample.
And here is the thing,
1) in that sample fill, RecolorSubtree is using IsAttributeSpecified and GetAttributeValue then utilizing paint->SetColor to change the color, not using SetAttributeValue.
2) SetAttributeValue is been used after GetAttributeValue for 'display' and not for fill
may be that is the case ?
I have tried to used the method used in the sample see the commented out code:
Assert(Succeeded( Element.GetAttributeValue('fill', IID_ID2D1SvgPaint, Pointer(Paint)) ));
but that did not work either. So I then tried to use a different overload to get the color and that worked. But setting it back produces the crash.
-
There is not much in the internet, just a Microsoft sample at https://github.com/microsoft/Windows-universal-samples/tree/master/Samples/D2DSvgImage/cpp which I am following.
But the element works fine with GetAttributeValue call. So it should be OK.
-
24 minutes ago, Kas Ob. said:Means nothing, as it depends on different factors, like the local variables initialized or not, the stack protection cookie, stack frame.. etc
So being different help with nothing here.
But lets approach this differently, is the value returned in OldColor with GetAttributeValue is right ? if yes then passing it to SetAttributeValue should be OK, i have no idea what POD means ?!, may be try with string type at first then switch to that POD.
"Crashes Access violation" this is not very helpful without the address triggering the AV with the invalid value trying to read, this will help you understand if the message have reading address XXXXX, is your stack in other word belongs to OldColor the pointer itself instead of the memory it pointing to.
And last, i would suggest to double check if you landing on the right function SetAttributeValue
https://docs.microsoft.com/en-us/windows/win32/direct2d/id2d1svgelement-setattributevalue-overload
The value of OldColor returned by GetAttributeValue is right. (I have a simple svg file and checked with the contents of the file). So GetAttributeValue works fine.
Access violation at 0x75db8cbx read of address 0x000000001
D2D1_SVG_ATTRIBUTE_POD_TYPE = DWord; {$EXTERNALSYM D2D1_SVG_ATTRIBUTE_POD_TYPE} const // The attribute is a D2D1_COLOR_F. D2D1_SVG_ATTRIBUTE_POD_TYPE_COLOR = D2D1_SVG_ATTRIBUTE_POD_TYPE(1);
I did check that the correct overload is called. (looked at the assembly code calliing the function: call dword ptr [eax+$7c] for GetAttributeValue , dword ptr [eax+$78] for SetAttributeValue , tripled checked with the C header file order of interface members etc).
MSDN description of SetAttributeValue overload used.
I am attaching the project source code in case anyone wants to have a go. The display of svg files works fine and now without using Vcl.Direct2D.
-
41 minutes ago, David Heffernan said:Problem could be how you call the function
OldColor: TD2D1ColorF; //works with correct results if Succeeded(Element.GetAttributeValue('fill', D2D1_SVG_ATTRIBUTE_POD_TYPE_COLOR, @OldColor, SizeOf(OldColor))) // Crashes Access violation Element.SetAttributeValue('fill', D2D1_SVG_ATTRIBUTE_POD_TYPE_COLOR, @OldColor, SizeOf(OldColor));
D2D1_SVG_ATTRIBUTE_POD_TYPE_COLOR = 1
The prolog of the two functions differ. Doesn't this mean the declaration should be different? But I am not sure what SetAttributeValue expects
-
For comparison the following method is GetAttributeValue:
/// <summary> /// Gets an attribute of this element as a POD type. Returns an error if the /// attribute is not specified. Returns an error if the attribute name is not valid /// on this element. Returns an error if the attribute cannot be expressed as the /// specified POD type. /// </summary> STDMETHOD(GetAttributeValue)( _In_ PCWSTR name, D2D1_SVG_ATTRIBUTE_POD_TYPE type, _Out_writes_bytes_(valueSizeInBytes) void *value, UINT32 valueSizeInBytes ) PURE;
which I am successfully using by translating to (same parameters)
function GetAttributeValue(name: LPWSTR; _type: D2D1_SVG_ATTRIBUTE_POD_TYPE; value: Pointer; valueSizeInBytes: UINT32): HResult; overload; stdcall;
However the prolog of GetAttributeValue is different:
564713C0 6690 nop 564713C2 55 push ebp 564713C3 8BEC mov ebp,esp 564713C5 83EC24 sub esp,$24 564713C8 8B4D08 mov ecx,[ebp+$08] 564713CB 53 push ebx 564713CC 8BD9 mov ebx,ecx 564713CE 56 push esi 564713CF 8D4108 lea eax,[ecx+$08] 564713D2 33C9 xor ecx,ecx 564713D4 85C0 test eax,eax 564713D6 57 push edi 564713D7 0F44D9 cmovz ebx,ecx 564713DA 6A08 push $08 564713DC 5A pop edx
-
In d2d1svg.h (Direct2D) there is the following declaration of the ID2D1SvgElement interface:
/// <summary> /// Sets an attribute of this element using a POD type. Returns an error if the /// attribute name is not valid on this element. Returns an error if the attribute /// cannot be expressed as the specified type. /// </summary> STDMETHOD(SetAttributeValue)( _In_ PCWSTR name, D2D1_SVG_ATTRIBUTE_POD_TYPE type, _In_reads_bytes_(valueSizeInBytes) CONST void *value, UINT32 valueSizeInBytes ) PURE;
D2D1_SVG_ATTRIBUTE_POD_TYPE = DWord;
I am translating this as
function SetAttributeValue(name: LPWSTR; _type: D2D1_SVG_ATTRIBUTE_POD_TYPE; value: Pointer; valueSizeInBytes: UINT32): HResult; overload; stdcall;
But it crashes when it is used.
The assembly prolog of SetAttributeValue is
564711F0 6690 nop 564711F2 55 push ebp 564711F3 8BEC mov ebp,esp 564711F5 83EC14 sub esp,$14 564711F8 8B4508 mov eax,[ebp+$08] 564711FB 33C9 xor ecx,ecx 564711FD 53 push ebx 564711FE 56 push esi 564711FF 57 push edi 56471200 8D5808 lea ebx,[eax+$08] 56471203 85DB test ebx,ebx 56471205 6A08 push $08 56471207 0F44C1 cmovz eax,ecx 5647120A 8945F8 mov [ebp-$08],eax 5647120D 5A pop edx
Any idea what I am doing wrong?
Thanks!
-
- FLRE is the fastest of all!
- One single pascal file which is good
- The author is a kind of genius
But
- not as extensively tested as PCRE
- poorly documented
- not very well supported
- the performance gain compared to PCRE+JIT is not that big
- System.RegularExpressions has a nicer interface
All-in-all I would stick to System.RegularExpressions at least if you add JIT.
- 2
-
25 minutes ago, Vincent Parrett said:Nice, however the lack of text support might be an issue. I pains me that windows doesn't have a fully featured svg render build it.. it's not like svg's are a new thing!
True. And for the last 3-4 years there was no improvement in Windows svg support. However converting text to path is a reasonable workaround. In any case it is not common to have text in toolbar icons etc.
-
I am not sure many know that since the Windows Creators update, svg parsing and painting is natively supported and is part of Direct2D. I wanted to test this Windows feature, however, the first obstacle was that the Direct2d headers that come with Delphi are very very old. There are two open tickets in https://quality.embarcadero.com/.
- Direct2D 1.1 support missing (open since XE7!)
- Direct2D 1.2 and 1.3 support missing
You may want to vote for them, since lack of good Direct2D support (includes DirectWrite) it is a bit of a shame.
I then looked at other Direct2D translations and found two that are regularly updated.
They both had some issues but that was a good start. It turned out that parsing and painting svg files to Canvas is quite straightforward. Once you establish a renderer (Vcl.Direct2d does this, but it is easy to do it from scratch) you can do everything with two lines of code.
fDeviceContext5.CreateSvgDocument(fStream, D2D1SizeF(ClientWidth, ClientHeight), fsvgDocument); fDeviceContext5.DrawSvgDocument(fsvgDocument);
You can check whether Svg is supported by:
if Supports( rt, ID2D1DeviceContext5, fDeviceContext5) then
And it is easy to do things like scaling, opacity, rotation, recoloring etc. The quality and speed appear to be quite good, but there are some limitations, the most important of which I think is the lack of support for the text element. I am attaching the source code of my test project (no dependencies) in case anyone wants to play with it. The Svg scales automatically as you resize the form.
- 4
-
1 hour ago, dummzeuch said:In 2011 Eric Grange blogged about a problem with the then current implementation of TCriticalSection and TMonitor:
According to Allen Bauer this was fixed for TMonitor in Delphi XE2:
I just looked at the code, it indeed has been done. But apparently nothing has been changed in TCriticalSection.
Is this still relevant?
If yes, is there a way to change the allocated memory of an object instance dynamically?
I just found that David Millington blogged about Custom object memory allocation in Delphi which seems to fit the bill.
I would use the TRTLCriticalSection which is a record defined in Windows.pas.
TRTLCriticalSection = record DebugInfo: PRTLCriticalSectionDebug; LockCount: Longint; RecursionCount: Longint; OwningThread: THandle; LockSemaphore: THandle; Reserved: ULONG_PTR; end;
A record helper is provided in SynchObjs.pas
TCriticalSectionHelper = record helper for TRTLCriticalSection procedure Initialize; inline; procedure Destroy; inline; procedure Free; inline; procedure Enter; inline; procedure Leave; inline; function TryEnter: Boolean; inline; end;
According to Eric It is much less prone to this issue (I don't have the reference though) and does not incur the overhead of object creation/destruction.
The SpinLock is another option. So is the Windows Slim reader writer (SRW) lock. And of course you can use TMonitor which nowadays is comparable in performance to the CriticalSection. (SpinLock and SRW locks are faster).
For anyone interested here is a record wrapper to SRW locks.
(* Multiple Read Exclusive Write lock based on Windows slim reader/writer (SRW) Locks. Can be also used instead of a critical session. Limitations: non-reentrant, not "fair" *) TSlimMREWSync = record private Lock: TRTLSRWLock; public procedure Create; procedure BeginRead; procedure EndRead; procedure BeginWrite; procedure EndWrite; function TryRead: Boolean; function TryWrite: Boolean; end; { TSMREWSync } procedure TSlimMREWSync.BeginRead; begin AcquireSRWLockShared(Lock); end; procedure TSlimMREWSync.BeginWrite; begin AcquireSRWLockExclusive(Lock); end; procedure TSlimMREWSync.Create; begin InitializeSRWLock(Lock); end; procedure TSlimMREWSync.EndRead; begin ReleaseSRWLockShared(Lock); end; procedure TSlimMREWSync.EndWrite; begin ReleaseSRWLockExclusive(Lock); end; function TSlimMREWSync.TryRead: Boolean; begin Result := TryAcquireSRWLockShared(Lock); end; function TSlimMREWSync.TryWrite: Boolean; begin Result := TryAcquireSRWLockExclusive(Lock); end;
- 1
-
Worked earlier on but now is down again.
-
I had the same problem. I though I had installed the patch through Getit but it was not actually installed. After reading this thread I installed by the command prompt. It appears that just clicking on the bat file via the File Explorer did not work despite getting the elevation prompt.
- 1
-
1 hour ago, dummzeuch said:Easy: Revolutionary Socialist Party
😉
lol. It reminded me of the Ecumenical Liberation Army from the Network film. Great film by the way.
-
1 minute ago, Edwin Yip said:But the patch is only available for a single specific version of Delphi
You can apply it manually to your own version (it only takes a couple of minutes, because the changes are few) and you only need to do it once). You can then submit a pull request with the patch in your Delphi version.
-
1 hour ago, Mahdi Safsafi said:@pyscripter I just made a benchmark against Perl regex. Yes its weird to compare a compiler vs interpreter ... but Perl beats Delphi own & study regex. However it failed to bit jit regex. A script and detailed result are attached.
Here it is not an issue of compiler/interpreter because PERL is using a C library anyway.
Perl uses its own regular expression engine not PCRE. There are many other options, Google RE, Intel's Hyperscan to mention a couple. PCRE+JIT is one of the fastest around and most widely used. I should not forget to mention FLRE written in Pascal, which is probably the fastest of all! Sometime ago I had posted in Google+ a benchmark comparing many of the above, But I not sure how to access Google+ material. Also note that the number of matches differs between Delphi and Perl. This is not surprising, because there are subtle differences in how these engines work.
-
There is an RSP https://quality.embarcadero.com/browse/RSP-21733 that asks for PCRE JIT support in the Delphi RTL. If you want the extra PCRE performance please vote for this.
Off-topic. What does RSP stand for?
- 1
-
8 hours ago, Edwin Yip said:Maybe it's easier to deploy if it's possible to patch at runtime with DDetours
Not possible I am afraid and not easier. You just need to add the patched System.RegularExpressionsAPI to your project uses clause.
-
Delphi wraps the PCRE library into the System.RegularExpressions unit. This unit provides a high-level, easy-to-use interface to PCRE. A limitation however is that it does not provide access to the Just-In-Time (JIT) compiler of PCRE. PCRE JIT can improve the performance of regular expression matching dramatically and is particularly useful, when you apply the same regular expression repetitively. The purpose of the Pcre-Jit-Delphi project is to patch the Delphi RTL in order to provide access to JIT. Please visit the project page at Github to see how you can use PCRE JIT in your projects.
Benchmark
The console project Benchmark.dpr in Demos folder compares the performance of the built-in Delphi regular expressions library, with the those of using Study without JIT and Study with JIT on a commonly used regular expression benchmark.
Here are the results I got from the 64 bit version.
Time | Match count ============================================================================== Delphi's own TRegEx: /Twain/ : 7.00 ms | 811 /(?i)Twain/ : 41.00 ms | 965 /[a-z]shing/ : 384.00 ms | 1540 /Huck[a-zA-Z]+|Saw[a-zA-Z]+/ : 461.00 ms | 262 /\b\w+nn\b/ : 588.00 ms | 262 /[a-q][^u-z]{13}x/ : 539.00 ms | 4094 /Tom|Sawyer|Huckleberry|Finn/ : 757.00 ms | 2598 /(?i)Tom|Sawyer|Huckleberry|Finn/ : 861.00 ms | 4152 /.{0,2}(Tom|Sawyer|Huckleberry|Finn)/ : 2615.00 ms | 2598 /.{2,4}(Tom|Sawyer|Huckleberry|Finn)/ : 2766.00 ms | 1976 /Tom.{10,25}river|river.{10,25}Tom/ : 455.00 ms | 2 /[a-zA-Z]+ing/ : 807.00 ms | 78423 /\s[a-zA-Z]{0,12}ing\s/ : 560.00 ms | 49659 /([A-Za-z]awyer|[A-Za-z]inn)\s/ : 789.00 ms | 209 /["'][^"']{0,30}[?!\.]["']/ : 321.00 ms | 8885 Total Time: 11963.00 ms ============================================================================== Delphi's own TRegEx with Study: /Twain/ : 6.00 ms | 811 /(?i)Twain/ : 41.00 ms | 965 /[a-z]shing/ : 316.00 ms | 1540 /Huck[a-zA-Z]+|Saw[a-zA-Z]+/ : 21.00 ms | 262 /\b\w+nn\b/ : 581.00 ms | 262 /[a-q][^u-z]{13}x/ : 413.00 ms | 4094 /Tom|Sawyer|Huckleberry|Finn/ : 28.00 ms | 2598 /(?i)Tom|Sawyer|Huckleberry|Finn/ : 217.00 ms | 4152 /.{0,2}(Tom|Sawyer|Huckleberry|Finn)/ : 2632.00 ms | 2598 /.{2,4}(Tom|Sawyer|Huckleberry|Finn)/ : 2785.00 ms | 1976 /Tom.{10,25}river|river.{10,25}Tom/ : 50.00 ms | 2 /[a-zA-Z]+ing/ : 759.00 ms | 78423 /\s[a-zA-Z]{0,12}ing\s/ : 563.00 ms | 49659 /([A-Za-z]awyer|[A-Za-z]inn)\s/ : 699.00 ms | 209 /["'][^"']{0,30}[?!\.]["']/ : 52.00 ms | 8885 Total Time: 9179.00 ms ============================================================================== Delphi's own TRegEx with JIT: /Twain/ : 11.00 ms | 811 /(?i)Twain/ : 14.00 ms | 965 /[a-z]shing/ : 12.00 ms | 1540 /Huck[a-zA-Z]+|Saw[a-zA-Z]+/ : 3.00 ms | 262 /\b\w+nn\b/ : 126.00 ms | 262 /[a-q][^u-z]{13}x/ : 154.00 ms | 4094 /Tom|Sawyer|Huckleberry|Finn/ : 22.00 ms | 2598 /(?i)Tom|Sawyer|Huckleberry|Finn/ : 61.00 ms | 4152 /.{0,2}(Tom|Sawyer|Huckleberry|Finn)/ : 277.00 ms | 2598 /.{2,4}(Tom|Sawyer|Huckleberry|Finn)/ : 346.00 ms | 1976 /Tom.{10,25}river|river.{10,25}Tom/ : 12.00 ms | 2 /[a-zA-Z]+ing/ : 84.00 ms | 78423 /\s[a-zA-Z]{0,12}ing\s/ : 156.00 ms | 49659 /([A-Za-z]awyer|[A-Za-z]inn)\s/ : 35.00 ms | 209 /["'][^"']{0,30}[?!\.]["']/ : 18.00 ms | 8885 Total Time: 1350.00 ms
As you can see the increase in performance is impressive.
Credits
Many thanks to @Mahdi Safsafi who provided the assembly code for __chkstk and other Delphi developers (@Kas Ob., @David Heffernan, @Remy Lebeau, @Fr0sT.Brutal) that have provided useful advice.
- 6
- 2
-
Still unable to login. Who do I need to contact?
-
I am not able to login for some reason.
Translation of C headers.
in RTL and Delphi Object Pascal
Posted · Edited by pyscripter
@Mahdi Safsafi Amazing stuff.
Questions:
It was just by accident that my GetAttributeCall was picking the correct overload!! That really confused me.