FPPS4/vulkan/vMetaManager.pas

266 lines
4.6 KiB
Plaintext

unit vMetaManager;
{$mode ObjFPC}{$H+}
interface
uses
SysUtils,
g23tree,
vDependence,
vImage;
type
PMetaKey=^TMetaKey;
TMetaKey=packed object
mtype:t_image_usage;
msize:DWORD;
mkey :TvImageKey;
function c(a,b:PMetaKey):Integer; static;
end;
TvCustomMeta=class(TvRefsObject)
Key:TMetaKey;
end;
TvMetaBuffer=class(TvCustomMeta)
rclear:Boolean;
end;
//
TvMetaHtile=class(TvCustomMeta)
private
function get_rclear:Boolean;
procedure set_rclear(b:Boolean);
public
buffer:TvMetaBuffer;
property rclear:Boolean read get_rclear write set_rclear;
end;
//
TvMetaCmask=class(TvCustomMeta)
private
function get_rclear:Boolean;
procedure set_rclear(b:Boolean);
public
buffer:TvMetaBuffer;
property rclear:Boolean read get_rclear write set_rclear;
end;
function FetchHtile (cmd:TvDependenciesObject;const F:TvImageKey;size:DWORD;force:Boolean=True):TvMetaHtile;
function FetchCmask (cmd:TvDependenciesObject;const F:TvImageKey;size:DWORD;force:Boolean=True):TvMetaCmask;
function FetchBuffer(cmd:TvDependenciesObject;addr:Pointer;size:DWORD;force:Boolean=True):TvMetaBuffer;
implementation
uses
kern_rwlock;
type
TvCustomMeta2Set=specialize T23treeSet<PMetaKey,TMetaKey>;
function TMetaKey.c(a,b:PMetaKey):Integer;
begin
//type
Result:=ord(ord(a^.mtype)>ord(b^.mtype))-ord(ord(a^.mtype)<ord(b^.mtype));
if (Result<>0) then Exit;
//addr
Result:=ord(a^.mkey.Addr>b^.mkey.Addr)-ord(a^.mkey.Addr<b^.mkey.Addr);
if (Result<>0) then Exit;
//size
Result:=ord(a^.msize>b^.msize)-ord(a^.msize<b^.msize);
if (Result<>0) then Exit;
//params
Result:=CompareNormalized(a^.mkey,b^.mkey);
end;
var
lock:Pointer=nil;
FMeta2Set:TvCustomMeta2Set;
//
function TvMetaHtile.get_rclear:Boolean; inline;
begin
Result:=buffer.rclear;
end;
procedure TvMetaHtile.set_rclear(b:Boolean); inline;
begin
buffer.rclear:=b;
end;
//
function TvMetaCmask.get_rclear:Boolean; inline;
begin
Result:=buffer.rclear;
end;
procedure TvMetaCmask.set_rclear(b:Boolean); inline;
begin
buffer.rclear:=b;
end;
//
function Key2CustomMeta(P:PMetaKey):TvCustomMeta; inline;
begin
Result:=TvCustomMeta(ptruint(P)-ptruint(@TvCustomMeta(nil).key));
end;
function _Find(const F:TMetaKey):TvCustomMeta;
var
i:TvCustomMeta2Set.Iterator;
begin
Result:=nil;
i:=FMeta2Set.find(@F);
if (i.Item<>nil) then
begin
Result:=Key2CustomMeta(i.Item^);
end;
end;
{
function _Find_be(const F:TMetaKey):TvCustomMeta;
var
i:TvCustomMeta2Set.Iterator;
P:PMetaKey;
begin
Result:=nil;
i:=FMeta2Set.find_be(@F);
if (i.Item<>nil) then
begin
P:=i.Item^;
if (P^.mtype<>F.mtype) then Exit(nil);
if (P^.msize<>F.msize) then Exit(nil);
if (P^.mkey.Addr<>F.mkey.Addr) then Exit(nil);
Result:=Key2CustomMeta(P);
end;
end;
function _Find_buffer(const F:TvImageKey;size:DWORD):TvCustomMeta;
var
M:TMetaKey;
begin
M.mtype:=iu_buffer;
M.mkey :=F;
M.msize:=size;
//
Result:=_Find_be(M);
end;
}
function _FetchMeta(mtype:t_image_usage;const F:TvImageKey;size:DWORD;force:Boolean):TvCustomMeta;
var
t:TvCustomMeta;
M:TMetaKey;
begin
Result:=nil;
M.mtype:=mtype;
M.mkey :=F;
M.msize:=size;
t:=_Find(M);
if (t<>nil) then
begin
//
end else
if force then
begin
case mtype of
iu_buffer:t:=TvMetaBuffer.Create;
iu_htile :t:=TvMetaHtile .Create;
iu_cmask :t:=TvMetaCmask .Create;
else;
end;
if (t<>nil) then
begin
t.Key:=M;
if FMeta2Set.Insert(@t.key) then
begin
t.Acquire(nil); //map ref
end;
end;
end;
Result:=t;
end;
function FetchHtile(cmd:TvDependenciesObject;const F:TvImageKey;size:DWORD;force:Boolean=True):TvMetaHtile;
var
B:TvImageKey;
begin
rw_wlock(lock);
Result:=TvMetaHtile(_FetchMeta(iu_htile,F,size,force));
if (Result<>nil) then
if (Result.buffer=nil) then
begin
//link buffer
B:=Default(TvImageKey);
B.Addr:=F.Addr;
//
Result.buffer:=TvMetaBuffer(_FetchMeta(iu_buffer,B,size,True));
end;
cmd.RefTo(Result);
rw_wunlock(lock);
end;
function FetchCmask(cmd:TvDependenciesObject;const F:TvImageKey;size:DWORD;force:Boolean=True):TvMetaCmask;
var
B:TvImageKey;
begin
rw_wlock(lock);
Result:=TvMetaCmask(_FetchMeta(iu_cmask,F,size,force));
if (Result<>nil) then
if (Result.buffer=nil) then
begin
//link buffer
B:=Default(TvImageKey);
B.Addr:=F.Addr;
//
Result.buffer:=TvMetaBuffer(_FetchMeta(iu_buffer,B,size,True));
end;
cmd.RefTo(Result);
rw_wunlock(lock);
end;
function FetchBuffer(cmd:TvDependenciesObject;addr:Pointer;size:DWORD;force:Boolean=True):TvMetaBuffer;
var
B:TvImageKey;
begin
B:=Default(TvImageKey);
B.Addr:=addr;
rw_wlock(lock);
Result:=TvMetaBuffer(_FetchMeta(iu_buffer,B,size,force));
cmd.RefTo(Result);
rw_wunlock(lock);
end;
end.