AllCharsTest.mesa
DIRECTORY Basics, BasicTime, CedarProcess, IISample, ImagerDevice, SF, IISampleExtras;
AllCharsTest: CEDAR PROGRAM IMPORTS Basics, BasicTime, CedarProcess, IISample, SF, IISampleExtras
~ BEGIN
call: BOOLTRUE;
AllChars: PROC [dst: IISample.SampleMap, chars: LIST OF ImagerDevice.CharMask, function: IISample.Function ← IISample.nullFunction, n: INT ← 1] RETURNS [microseconds: LONG CARDINAL] ~ {
pulses: BasicTime.Pulses;
gen: IISampleExtras.RawGenerator ~ {
box: SF.Box ~ IISample.GetBox[dst];
s: INTEGER ← box.min.s;
f: INTEGER ← box.min.f;
nextS: INTEGER ← 0;
FOR each: LIST OF ImagerDevice.CharMask ← chars, each.rest UNTIL each = NIL DO
WITH each.first SELECT FROM
raster: REF ImagerDevice.CharMaskRep.raster => {
IF f+NAT[raster.fSizeBB] > box.max.f THEN { f ← 0; s ← nextS };
IF f+NAT[raster.fSizeBB] <= box.max.f AND NAT[s+raster.sSizeBB] <= box.max.s THEN {
box: SF.Box ~ SF.Displace[[max: [raster.sSizeBB, raster.fSizeBB]], [s, f]];
bitsPerLine: NAT ~ Basics.BITAND[raster.fSizeBB+15, 0FFF0H];
IF call THEN TRUSTED { rawAction[box, bitsPerLine, [word: @(raster[0]), bit: 0]] };
f ← box.max.f;
nextS ← MAX[nextS, box.max.s];
};
};
ENDCASE => NULL;
ENDLOOP;
};
CedarProcess.SetPriority[foreground];
pulses ← BasicTime.GetClockPulses[];
FOR i: INT IN [0..n) DO IISampleExtras.RawTransfer[dst, gen, function] ENDLOOP;
pulses ← BasicTime.GetClockPulses[]-pulses;
CedarProcess.SetPriority[normal];
microseconds ← BasicTime.PulsesToMicroseconds[pulses];
};
AllChars2: PROC [dst: IISample.SampleMap, chars: LIST OF ImagerDevice.CharMask, function: IISample.Function ← IISample.nullFunction, n: INT ← 1] RETURNS [microseconds: LONG CARDINAL] ~ {
pulses: BasicTime.Pulses;
maxN: NAT ~ IISampleExtras.rawArraySize;
Gen: PROC ~ TRUSTED {
box: SF.Box ~ IISample.GetBox[dst];
s: INTEGER ← box.min.s;
f: INTEGER ← box.min.f;
nextS: INTEGER ← 0;
i: NAT ← 0;
a: ARRAY [0..maxN) OF IISampleExtras.RawDescriptor;
a0: POINTER TO IISampleExtras.RawDescriptor ~ @(a[0]);
p: POINTER TO IISampleExtras.RawDescriptor ← a0;
FOR each: LIST OF ImagerDevice.CharMask ← chars, each.rest UNTIL each = NIL DO
WITH each.first SELECT FROM
raster: REF ImagerDevice.CharMaskRep.raster => {
IF f+NAT[raster.fSizeBB] > box.max.f THEN { f ← 0; s ← nextS };
IF f+NAT[raster.fSizeBB] <= box.max.f AND NAT[s+raster.sSizeBB] <= box.max.s THEN {
IF i = maxN THEN { IISampleExtras.MultipleTransfer[dst, i, @a, function]; i ← 0; p ← a0 };
p^.box ← SF.Displace[[max: [raster.sSizeBB, raster.fSizeBB]], [s, f]];
f ← p^.box.max.f;
nextS ← MAX[nextS, p^.box.max.s];
p^.bitsPerLine ← Basics.BITAND[raster.fSizeBB+15, 0FFF0H];
p^.basePointer ← @(raster[0]);
p ← p + SIZE[IISampleExtras.RawDescriptor];
i ← i + 1;
};
};
ENDCASE => NULL;
ENDLOOP;
IF i # 0 THEN { IISampleExtras.MultipleTransfer[dst, i, @a, function]; i ← 0; p ← a0 };
};
CedarProcess.SetPriority[foreground];
pulses ← BasicTime.GetClockPulses[];
FOR i: INT IN [0..n) DO Gen[] ENDLOOP;
pulses ← BasicTime.GetClockPulses[]-pulses;
CedarProcess.SetPriority[normal];
microseconds ← BasicTime.PulsesToMicroseconds[pulses];
};
END.
ColorDisplay on 1 640x480
← &b ← IISample.MapFromFrameBuffer[Terminal.GetColorFrameBufferA[Terminal.Current[]]]
← IISample.Clear[&b]
← Test.AllChars[&b, ImagerCache.GetList[ImagerCache.GetNamedCache[$Bitmap, 4000]], [null,null]]
← NIL=(&list ← ImagerCache.GetList[ImagerCache.GetNamedCache[$Bitmap, 4000]])
← IISample.Clear[&b]
← Test.AllChars[&b, ImagerCache.GetList[ImagerCache.GetNamedCache[$Bitmap, 4000]], [null,null], 10]
← Test.AllChars2[&b, ImagerCache.GetList[ImagerCache.GetNamedCache[$Bitmap, 4000]], [null,null], 10]
Character Transfer Times
(all times in microseconds per character, on a dorado)
Callback:  84.29583
Array:  79.58922
Callback, no BITBLT:  69.13633
Array, no BITBLT:  63.00931
Test loop overhead:  31.38286
Callback, net:  52.91297
Array, net:  48.20636
ratio:  1.097635
BITBLT time:  15.8697
max BITBLT percentage:  100*(15.8697/48.20636) = 32.92035
min BITBLT percentage:  100*(15.8697/84.29583) = 18.8262