coder0xff
January 21st, 2005, 12:39 AM
The function in question is RenderControl::ResetDevice. When it calls device->Reset(...) it is very slow to complete this call or even hangs. Some functions removed to fit in the thread
#include "stdafx.h"
#include "RenderControl.h"
namespace Render
{
void RenderControl::Refresh()
{
if (Enabled==false)
{
System::Drawing::Graphics* gfx=CreateGraphics();
gfx->DrawString(S"RenderControl not enabled",new System::Drawing::Font(S"Courier New",24),System::Drawing::Brushes::Black, System::Drawing::PointF(0,0));
return;
}
if (D3DDevice==0) return;
if (VerifyDeviceReady())
{
if (UserRendering==false)
{
D3DDevice->Clear(Microsoft::DirectX::Direct3D::ClearFlags::Target, BackColor, 1.0f, 0);
D3DDevice->BeginScene();
RenderAll();
D3DDevice->EndScene();
D3DDevice->Present();
}
else
{
D3DDevice->Clear(Microsoft::DirectX::Direct3D::ClearFlags::Target, BackColor, 1.0f, 0);
D3DDevice->BeginScene();
if (AutoRender!=0)
ProcessRenderList(AutoRender);
RenderEvent(this);
D3DDevice->EndScene();
D3DDevice->Present();
}
}
}
Render::Quads* RenderControl::get_Quads()
{
return quads;
}
int RenderControl::Initialize()
{
CreateArrays();
int temp=InitD3D();
DelegateEvents();
Zoom=1;
return temp;
}
void RenderControl::CreateArrays()
{
quads=new Render::Quads();
lines=new Render::Lines();
}
Microsoft::DirectX::Direct3D::Device* RenderControl::SelectD3DDevice()
{
using namespace Microsoft::DirectX::Direct3D;
//try
//{
// Now setup our D3D stuff
PresentParameters* presentParametersArray __gc[] = new PresentParameters* __gc[1];
presentParametersArray[0]=new PresentParameters();
presentParametersArray[0]->Windowed=true;
presentParametersArray[0]->SwapEffect = SwapEffect::Discard;
presentParametersArray[0]->BackBufferCount=1;
return new Microsoft::DirectX::Direct3D::Device(0, DeviceType::Hardware, this->Handle,
CreateFlags::SoftwareVertexProcessing, presentParametersArray);
//}
//catch (Microsoft::DirectX::DirectXException*)
//{
// return 0;
//}
}
int RenderControl::InitD3D()
{
D3DDevice=SelectD3DDevice();
if (D3DDevice==0) return -1;
ConfigureD3DDevice();
SetupTransformations();
return 0;
}
bool RenderControl::ResetDevice()
{
if (Enabled==false) return false;
if (DeviceCanReset)
{
doingReset=true;
if (linesBuffer!=0) linesBuffer->Dispose();
linesBuffer=0;
LinesBufferCreated=false;
static int resetCounts=0;
resetCounts++;
if (resetCounts==10)
{
resetCounts=0;
RecreateDevice();
doingReset=false;
return true;
}
using namespace Microsoft::DirectX::Direct3D;
PresentParameters* presentParametersArray __gc[] = new PresentParameters* __gc[1];
presentParametersArray[0]=new PresentParameters();
presentParametersArray[0]->Windowed=true;
presentParametersArray[0]->SwapEffect = SwapEffect::Discard;
presentParametersArray[0]->BackBufferCount=1;
D3DDevice->Reset(presentParametersArray);
DeviceNeedsReset=false;
presentParametersArray[0]=0;
delete presentParametersArray;
doingReset=false;
ConfigureD3DDevice();
UpdateLinesBuffer();
return true;
}
doingReset=false;
return false;
}
void RenderControl::RecreateDevice()
{
if (D3DDevice!=0 && D3DDevice->Disposed==false)
D3DDevice->Dispose();
InitD3D();
ConfigureD3DDevice();
CreateLinesBuffer();
D3DDevice->DeviceLost+=new System::EventHandler(this, &RenderControl::OnDeviceLost);
D3DDevice->DeviceReset+=new System::EventHandler(this, &RenderControl::OnDeviceReset);
for (int attachQuads=0;attachQuads<quads->Count;attachQuads++)
{
dynamic_cast<Render::Quad*>(quads->Item[attachQuads])->VerifyDevice();
}
}
void RenderControl::DelegateEvents()
{
D3DDevice->DeviceLost+=new System::EventHandler(this, &RenderControl::OnDeviceLost);
D3DDevice->DeviceReset+=new System::EventHandler(this, &RenderControl::OnDeviceReset);
quads->Added+=new Render::Quads::ArrayChangedHandler(this, &RenderControl::QuadsAddedHandler);
quads->Removed+=new Render::Quads::ArrayChangedHandler(this, &RenderControl::QuadsRemovedHandler);
lines->Added+=new Render::Lines::ArrayChangedHandler(this, &RenderControl::LinesAddedHandler);
lines->Removed+=new Render::Lines::ArrayChangedHandler(this, &RenderControl::LinesRemovedHandler);
lineAlteredHandlerDelegate=new Render::Line::LineAlteredHandler(this, &RenderControl::LineAlteredHandler);
}
void RenderControl::OnDeviceLost(System::Object* sender, System::EventArgs* e)
{
if (doingReset) return;
DeviceNeedsReset=true;
}
bool RenderControl::get_DeviceCanReset()
{
if (Enabled==false) return false;
using namespace Microsoft::DirectX::Direct3D;
int result=0;
int *rp=&result;
D3DDevice->CheckCooperativeLevel(rp);
rp=0;
if (ClientSize.Width<1 || ClientSize.Height<1)
{
return false;
}
if (result==ResultCode::Success) return true;
if (result==ResultCode::DeviceNotReset) return true;
return false;
}
bool RenderControl::VerifyDeviceReady()
{
if (Enabled==false) return false;
using namespace Microsoft::DirectX::Direct3D;
int result=0;
int *rp=&result;
D3DDevice->CheckCooperativeLevel(rp);
if (result==ResultCode::Success)
{
DeviceNeedsReset=false;
return true;
}
if (DeviceNeedsReset==false)
{
RecreateDevice();
DeviceNeedsReset=true;
return VerifyDeviceReady();
}
return ResetDevice();
}
void RenderControl::ConfigureD3DDevice()
{
using namespace Microsoft::DirectX;
using namespace Microsoft::DirectX::Direct3D;
D3DDevice->RenderState->CullMode=Microsoft::DirectX::Direct3D::Cull::None;
D3DDevice->RenderState->Lighting=false;
D3DDevice->RenderState->AlphaBlendEnable=true;
D3DDevice->RenderState->SourceBlend=Direct3D::Blend::SourceAlpha;
D3DDevice->RenderState->DestinationBlend=Direct3D::Blend::InvSourceAlpha;
//TextureStateManager* textureState=D3DDevice->TextureState->TextureState[0];
D3DDevice->SetSamplerState(0, SamplerStageStates::MinFilter, TextureFilter::Linear);
D3DDevice->SetSamplerState(0, SamplerStageStates::MagFilter, TextureFilter::Linear);
State=None;
}
void RenderControl::SetupTransformations()
{
using namespace Microsoft::DirectX;
using namespace Microsoft::DirectX::Direct3D;
D3DDevice->Transform->World=Matrix::Identity;
D3DDevice->Transform->View=Matrix::Translation(-focus.X, -focus.Y, 0);
D3DDevice->Transform->Projection=Microsoft::DirectX::Matrix::OrthoLH(ClientSize.Width/zoom,-ClientSize.Height/zoom,1,100);
}
void RenderControl::OnDeviceReset(System::Object* sender, System::EventArgs* e)
{
if (doingReset) return;
ConfigureD3DDevice();
for (int attachQuads=0;attachQuads<quads->Count;attachQuads++)
{
dynamic_cast<Render::Quad*>(quads->Item[attachQuads])->VerifyDevice();
}
}
void RenderControl::OnCreateLinesVertexBuffer(System::Object* sender, System::EventArgs* e)
{
if (doingReset) return;
UpdateLinesBuffer();
}
void RenderControl::CreateLinesBuffer()
{
if (VerifyDeviceReady())
{
Microsoft::DirectX::Direct3D::CustomVertex::PositionColored temp;
linesBuffer=new Microsoft::DirectX::Direct3D::VertexBuffer(
__box(temp)->GetType(), lines->Count*2+1, D3DDevice,
Microsoft::DirectX::Direct3D::Usage::WriteOnly,
Microsoft::DirectX::Direct3D::CustomVertex::PositionColored::Format,
Microsoft::DirectX::Direct3D::Pool::Default);
LinesBufferCreated=true;
linesBuffer->Created+=new System::EventHandler(this, RenderControl::OnCreateLinesVertexBuffer);
OnCreateLinesVertexBuffer(0, 0);
}
}
void RenderControl::ComputeEndPoints(int base_index, Line* l)
{
Microsoft::DirectX::Direct3D::CustomVertex::PositionColored temp;
temp.Color=l->C1.ToArgb();
temp.X=l->X1;
temp.Y=l->Y1;
temp.Z=10;
linesArray[base_index++]=temp;
temp.Color=l->C2.ToArgb();
temp.X=l->X2;
temp.Y=l->Y2;
linesArray[base_index]=temp;
linesDirty=true;
}
void RenderControl::FillLinesArray()
{
linesArray=new Microsoft::DirectX::Direct3D::CustomVertex::PositionColored __gc[lines->Count*2];
for (int createVerts=0; createVerts<lines->Count; createVerts++)
{
int base_index=createVerts*2;
ComputeEndPoints(base_index, dynamic_cast<Line*>(lines->Item[createVerts]));
}
}
void RenderControl::UpdateLinesBuffer()
{
if (VerifyDeviceReady() && LinesBufferCreated)
{
if (linesBuffer==0) CreateLinesBuffer();
if (linesArray==0) return;
if (linesArray->Count==0) return;
Microsoft::DirectX::GraphicsStream* stream = linesBuffer->Lock(0, 0, Microsoft::DirectX::Direct3D::LockFlags::None);
stream->Write(linesArray);
linesBuffer->Unlock();
linesDirty=false;
}
}
void RenderControl::OnPaint(System::Windows::Forms::PaintEventArgs* pe)
{
Refresh();
}
void RenderControl::OnResize(System::EventArgs* e)
{
ResetDevice();
SetupTransformations();
Refresh();
}
}
#include "stdafx.h"
#include "RenderControl.h"
namespace Render
{
void RenderControl::Refresh()
{
if (Enabled==false)
{
System::Drawing::Graphics* gfx=CreateGraphics();
gfx->DrawString(S"RenderControl not enabled",new System::Drawing::Font(S"Courier New",24),System::Drawing::Brushes::Black, System::Drawing::PointF(0,0));
return;
}
if (D3DDevice==0) return;
if (VerifyDeviceReady())
{
if (UserRendering==false)
{
D3DDevice->Clear(Microsoft::DirectX::Direct3D::ClearFlags::Target, BackColor, 1.0f, 0);
D3DDevice->BeginScene();
RenderAll();
D3DDevice->EndScene();
D3DDevice->Present();
}
else
{
D3DDevice->Clear(Microsoft::DirectX::Direct3D::ClearFlags::Target, BackColor, 1.0f, 0);
D3DDevice->BeginScene();
if (AutoRender!=0)
ProcessRenderList(AutoRender);
RenderEvent(this);
D3DDevice->EndScene();
D3DDevice->Present();
}
}
}
Render::Quads* RenderControl::get_Quads()
{
return quads;
}
int RenderControl::Initialize()
{
CreateArrays();
int temp=InitD3D();
DelegateEvents();
Zoom=1;
return temp;
}
void RenderControl::CreateArrays()
{
quads=new Render::Quads();
lines=new Render::Lines();
}
Microsoft::DirectX::Direct3D::Device* RenderControl::SelectD3DDevice()
{
using namespace Microsoft::DirectX::Direct3D;
//try
//{
// Now setup our D3D stuff
PresentParameters* presentParametersArray __gc[] = new PresentParameters* __gc[1];
presentParametersArray[0]=new PresentParameters();
presentParametersArray[0]->Windowed=true;
presentParametersArray[0]->SwapEffect = SwapEffect::Discard;
presentParametersArray[0]->BackBufferCount=1;
return new Microsoft::DirectX::Direct3D::Device(0, DeviceType::Hardware, this->Handle,
CreateFlags::SoftwareVertexProcessing, presentParametersArray);
//}
//catch (Microsoft::DirectX::DirectXException*)
//{
// return 0;
//}
}
int RenderControl::InitD3D()
{
D3DDevice=SelectD3DDevice();
if (D3DDevice==0) return -1;
ConfigureD3DDevice();
SetupTransformations();
return 0;
}
bool RenderControl::ResetDevice()
{
if (Enabled==false) return false;
if (DeviceCanReset)
{
doingReset=true;
if (linesBuffer!=0) linesBuffer->Dispose();
linesBuffer=0;
LinesBufferCreated=false;
static int resetCounts=0;
resetCounts++;
if (resetCounts==10)
{
resetCounts=0;
RecreateDevice();
doingReset=false;
return true;
}
using namespace Microsoft::DirectX::Direct3D;
PresentParameters* presentParametersArray __gc[] = new PresentParameters* __gc[1];
presentParametersArray[0]=new PresentParameters();
presentParametersArray[0]->Windowed=true;
presentParametersArray[0]->SwapEffect = SwapEffect::Discard;
presentParametersArray[0]->BackBufferCount=1;
D3DDevice->Reset(presentParametersArray);
DeviceNeedsReset=false;
presentParametersArray[0]=0;
delete presentParametersArray;
doingReset=false;
ConfigureD3DDevice();
UpdateLinesBuffer();
return true;
}
doingReset=false;
return false;
}
void RenderControl::RecreateDevice()
{
if (D3DDevice!=0 && D3DDevice->Disposed==false)
D3DDevice->Dispose();
InitD3D();
ConfigureD3DDevice();
CreateLinesBuffer();
D3DDevice->DeviceLost+=new System::EventHandler(this, &RenderControl::OnDeviceLost);
D3DDevice->DeviceReset+=new System::EventHandler(this, &RenderControl::OnDeviceReset);
for (int attachQuads=0;attachQuads<quads->Count;attachQuads++)
{
dynamic_cast<Render::Quad*>(quads->Item[attachQuads])->VerifyDevice();
}
}
void RenderControl::DelegateEvents()
{
D3DDevice->DeviceLost+=new System::EventHandler(this, &RenderControl::OnDeviceLost);
D3DDevice->DeviceReset+=new System::EventHandler(this, &RenderControl::OnDeviceReset);
quads->Added+=new Render::Quads::ArrayChangedHandler(this, &RenderControl::QuadsAddedHandler);
quads->Removed+=new Render::Quads::ArrayChangedHandler(this, &RenderControl::QuadsRemovedHandler);
lines->Added+=new Render::Lines::ArrayChangedHandler(this, &RenderControl::LinesAddedHandler);
lines->Removed+=new Render::Lines::ArrayChangedHandler(this, &RenderControl::LinesRemovedHandler);
lineAlteredHandlerDelegate=new Render::Line::LineAlteredHandler(this, &RenderControl::LineAlteredHandler);
}
void RenderControl::OnDeviceLost(System::Object* sender, System::EventArgs* e)
{
if (doingReset) return;
DeviceNeedsReset=true;
}
bool RenderControl::get_DeviceCanReset()
{
if (Enabled==false) return false;
using namespace Microsoft::DirectX::Direct3D;
int result=0;
int *rp=&result;
D3DDevice->CheckCooperativeLevel(rp);
rp=0;
if (ClientSize.Width<1 || ClientSize.Height<1)
{
return false;
}
if (result==ResultCode::Success) return true;
if (result==ResultCode::DeviceNotReset) return true;
return false;
}
bool RenderControl::VerifyDeviceReady()
{
if (Enabled==false) return false;
using namespace Microsoft::DirectX::Direct3D;
int result=0;
int *rp=&result;
D3DDevice->CheckCooperativeLevel(rp);
if (result==ResultCode::Success)
{
DeviceNeedsReset=false;
return true;
}
if (DeviceNeedsReset==false)
{
RecreateDevice();
DeviceNeedsReset=true;
return VerifyDeviceReady();
}
return ResetDevice();
}
void RenderControl::ConfigureD3DDevice()
{
using namespace Microsoft::DirectX;
using namespace Microsoft::DirectX::Direct3D;
D3DDevice->RenderState->CullMode=Microsoft::DirectX::Direct3D::Cull::None;
D3DDevice->RenderState->Lighting=false;
D3DDevice->RenderState->AlphaBlendEnable=true;
D3DDevice->RenderState->SourceBlend=Direct3D::Blend::SourceAlpha;
D3DDevice->RenderState->DestinationBlend=Direct3D::Blend::InvSourceAlpha;
//TextureStateManager* textureState=D3DDevice->TextureState->TextureState[0];
D3DDevice->SetSamplerState(0, SamplerStageStates::MinFilter, TextureFilter::Linear);
D3DDevice->SetSamplerState(0, SamplerStageStates::MagFilter, TextureFilter::Linear);
State=None;
}
void RenderControl::SetupTransformations()
{
using namespace Microsoft::DirectX;
using namespace Microsoft::DirectX::Direct3D;
D3DDevice->Transform->World=Matrix::Identity;
D3DDevice->Transform->View=Matrix::Translation(-focus.X, -focus.Y, 0);
D3DDevice->Transform->Projection=Microsoft::DirectX::Matrix::OrthoLH(ClientSize.Width/zoom,-ClientSize.Height/zoom,1,100);
}
void RenderControl::OnDeviceReset(System::Object* sender, System::EventArgs* e)
{
if (doingReset) return;
ConfigureD3DDevice();
for (int attachQuads=0;attachQuads<quads->Count;attachQuads++)
{
dynamic_cast<Render::Quad*>(quads->Item[attachQuads])->VerifyDevice();
}
}
void RenderControl::OnCreateLinesVertexBuffer(System::Object* sender, System::EventArgs* e)
{
if (doingReset) return;
UpdateLinesBuffer();
}
void RenderControl::CreateLinesBuffer()
{
if (VerifyDeviceReady())
{
Microsoft::DirectX::Direct3D::CustomVertex::PositionColored temp;
linesBuffer=new Microsoft::DirectX::Direct3D::VertexBuffer(
__box(temp)->GetType(), lines->Count*2+1, D3DDevice,
Microsoft::DirectX::Direct3D::Usage::WriteOnly,
Microsoft::DirectX::Direct3D::CustomVertex::PositionColored::Format,
Microsoft::DirectX::Direct3D::Pool::Default);
LinesBufferCreated=true;
linesBuffer->Created+=new System::EventHandler(this, RenderControl::OnCreateLinesVertexBuffer);
OnCreateLinesVertexBuffer(0, 0);
}
}
void RenderControl::ComputeEndPoints(int base_index, Line* l)
{
Microsoft::DirectX::Direct3D::CustomVertex::PositionColored temp;
temp.Color=l->C1.ToArgb();
temp.X=l->X1;
temp.Y=l->Y1;
temp.Z=10;
linesArray[base_index++]=temp;
temp.Color=l->C2.ToArgb();
temp.X=l->X2;
temp.Y=l->Y2;
linesArray[base_index]=temp;
linesDirty=true;
}
void RenderControl::FillLinesArray()
{
linesArray=new Microsoft::DirectX::Direct3D::CustomVertex::PositionColored __gc[lines->Count*2];
for (int createVerts=0; createVerts<lines->Count; createVerts++)
{
int base_index=createVerts*2;
ComputeEndPoints(base_index, dynamic_cast<Line*>(lines->Item[createVerts]));
}
}
void RenderControl::UpdateLinesBuffer()
{
if (VerifyDeviceReady() && LinesBufferCreated)
{
if (linesBuffer==0) CreateLinesBuffer();
if (linesArray==0) return;
if (linesArray->Count==0) return;
Microsoft::DirectX::GraphicsStream* stream = linesBuffer->Lock(0, 0, Microsoft::DirectX::Direct3D::LockFlags::None);
stream->Write(linesArray);
linesBuffer->Unlock();
linesDirty=false;
}
}
void RenderControl::OnPaint(System::Windows::Forms::PaintEventArgs* pe)
{
Refresh();
}
void RenderControl::OnResize(System::EventArgs* e)
{
ResetDevice();
SetupTransformations();
Refresh();
}
}