TCustomDX10Context.CheckDevice中的异常清除界面

时间:2014-06-06 10:54:35

标签: delphi delphi-xe3

这是我previous question的后续跟进。我意识到自己在那个问题上自己缩小了问题的能力很差,道歉。我现在对正在发生的事情有一个非常具体的想法,所以希望有人能够把我推向正确的方向。

SSCCE:

program SSCCE;

{$APPTYPE CONSOLE}

{$R *.res}

uses System.SysUtils, FMX.Context.DX10;

begin
  try
    TCustomDX10Context.CheckDevice;
    WriteLn('Everything went fine, guess we have to dig deeper.');
  except
    on E: Exception do Writeln(E.ClassName, ': ', E.Message);
  end;
  Write('Press enter to exit.');
  ReadLn;
end.

CheckDevice在@IntfClear中产生访问冲突。这是FMX.Context.DX10中的CheckDevice的代码:

class function TCustomDX10Context.CheckDevice: TD3D10DriverType;
var
  dx10lib: THandle;
  g_pd3dDevice: ID3D10Device1;
begin
  if not FChecked then
  begin
    FChecked := True;
    FDriverType := D3D10_DRIVER_TYPE_NULL;
    dx10lib := LoadLibrary(D3D10_1_dll);
    if dx10lib <> 0 then
    try
      if GlobalUseDX10Software then
        FDriverType := D3D10_DRIVER_TYPE_WARP
      else begin
        if GlobalUseDX10 then
        begin
          { check for support for DX10 hardware }
          SaveClearFPUState;
          try
            if GetProcAddress(dx10lib, 'D3D10CreateDevice1') <> nil then
            begin
              if Succeeded(D3D10CreateDevice1(nil, D3D10_DRIVER_TYPE_HARDWARE, 0, D3D10_CREATE_DEVICE_BGRA_SUPPORT, D3D10_FEATURE_LEVEL_10_1, D3D10_1_SDK_VERSION, g_pd3dDevice)) then
              begin
                g_pd3dDevice := nil;
                FDriverType := D3D10_DRIVER_TYPE_HARDWARE;
              end;
            end;
          finally
            RestoreFPUState;
          end;
        end;
      end;
    finally
      FreeLibrary(dx10Lib);
    end;
  end;
  Result := FDriverType;
end;

我已经让遇到问题的用户尝试了一些变体,我可以确认,只要g_pd3dDevice的引用超出范围,就会调用@IntfClear并随后生成访问违规。

0040e028 +010 <...>.exe System            191  +0 @IntfClear
0096a360 +0d0 <...>.exe FMX.Context.DX10  314 +20 TCustomDX10Context.CheckDevice
009759a1 +005 <...>.exe FMX.Canvas.D2D            RegisterCanvasClasses
009900b4 +000 <...>.exe FMX.Platform.Win 3404  +0 TPlatformWin.RegisterCanvasClasses
009d575a +056 <...>.exe FMX.Types                 TCanvasManager.GetDefaultCanvas
009d56f2 +00e <...>.exe FMX.Types                 TCanvasManager.CreateFromWindow

314是成功进行API调用后被g_pd3dDevice标记的行,注释掉该行会在函数结束时用完范围之后清除接口时导致AV出现。这可能是由D3D10CreateDevice1返回无效设备引起的,还是还有其他事情发生?此外,由于AV出现在@IntfClear我不认为我可以尝试除了它并吃掉它,即使这可能不会做太多好事......

0 个答案:

没有答案