首页
社区
课程
招聘
[求助]ddraw 锁定 surface 速度慢
发表于: 2012-2-23 10:08 6983

[求助]ddraw 锁定 surface 速度慢

2012-2-23 10:08
6983
小弟搞了一个 DDraw截图 运行中发现 Lock 后 只要一复制 lpSurface 就会卡的要命,但是你在LOCK 中操作 其他的内存复制创建什么的一点影响也没有晕了,没办法上来求助下。

                DDSURFACEDESC2 ddsd;
                ZeroMemory(&ddsd, sizeof(ddsd));
                ddsd.dwSize = sizeof(ddsd);

                if (lpDDSrcSurface->Lock(NULL, &ddsd, DDLOCK_WAIT, NULL) == DD_OK)
                {
                        GetTimeStart();
                       

                        dPrintf("%d\n",ddsd.ddpfPixelFormat.dwRGBBitCount);

                        dPrintf("%d\n",ddsd.lPitch*ddsd.dwHeight);

                        PBYTE pDataMap = new BYTE[ddsd.lPitch*ddsd.dwHeight];

                        RtlCopyMemory(pData, ddsd.lpSurface, ddsd.lPitch*ddsd.dwHeight);

                        delete[]pDataMap;

                        pDataMap = NULL;
                                                  dPrintf("%d\n",GetTimeStop());
}
以上的代码很简单就是 锁住后 复制 DX内存块到我创建的内存,竟然耗时 1400毫秒。

大家帮帮忙

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (8)
雪    币: 2105
活跃值: (424)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
2
自己维护一块内存池 不要总是去分配。

还有 不知道你的计数用的什么 是否确定是1.4秒。
2012-2-23 10:38
0
雪    币: 773
活跃值: (442)
能力值: ( LV9,RANK:200 )
在线值:
发帖
回帖
粉丝
3
当然确定,其实就是 TICK的封装,不是内存池的问题是只要操作 ddsd.lpSurface 这个指针就速度变慢,你不操作他,你复制10个那么大小的内存也没问题。
2012-2-23 17:07
0
雪    币: 2105
活跃值: (424)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
4
int CCaptureFrame::CaptureFrameDX8(IDirect3DDevice8* pDevice)
{
	dbgprintf("fps=%d", frameRate.m_curFPS);
	IDirect3DSurface8 *pBackBuffer = 0;
	if (frameRate.CheckFrameRate()==0)
	{
		if (GetFrameInfoDX8(pDevice, &pBackBuffer)==0)
		{
			//need capture
			switch (m_bbFormat)
			{
			case D3DFMT_R8G8B8:
			case D3DFMT_A8R8G8B8:
			case D3DFMT_X8R8G8B8:
			case D3DFMT_R5G6B5:
			case D3DFMT_X1R5G5B5:
				break;
			default:
				dynlog.Log("CaptureFrameDX8 Error -1");
				return -1;
			}
			
			HRESULT hRes;
			
			// copy rect to a new surface and lock the rect there.
			// NOTE: apparently, this works faster than locking a rect on the back buffer itself.
			// LOOKS LIKE: reading from the backbuffer is faster via CopyRects, but writing
			// is faster if done directly.
			if (m_pSurfTemp==NULL || m_bFrameInfoChg)
			{
				m_bFrameInfoChg = FALSE;
				if (m_pSurfTemp) m_pSurfTemp->Release();
				hRes = pDevice->CreateImageSurface(m_bbSize.cx, m_bbSize.cy, m_bbFormat, 
					&m_pSurfTemp);
				if (FAILED(hRes))
				{
					if(pBackBuffer) pBackBuffer->Release();
					dynlog.Log("CaptureFrameDX8 Error -3 hres=%X", hRes);
					return -3;
				}
			}
			
			RECT Rect = {0, 0, m_bbSize.cx, m_bbSize.cy};
			POINT points[] = {{0, 0}};
			
			hRes = pDevice->CopyRects(pBackBuffer, &Rect, 1, m_pSurfTemp, points);
			if (FAILED(hRes))
			{
				if(pBackBuffer) pBackBuffer->Release();
				dynlog.Log("CaptureFrameDX8 Error -4 hres=%X", hRes);
				return -4;
			}
			
			D3DLOCKED_RECT lockedSrcRect;
			RECT newRect = {0, 0, m_bbSize.cx, m_bbSize.cy};
			
			hRes = m_pSurfTemp->LockRect(&lockedSrcRect, &newRect, 0);
			if (FAILED(hRes))
			{
				if(pBackBuffer) pBackBuffer->Release();
				dynlog.Log("CaptureFrameDX8 Error -5");
				return -5;
			}
			int size = m_bbSize.cx*m_bbSize.cy*3;
			CVideoFrame * frame = m_aviFile.GetAvailFrame(size);
			//m_aviFile.m_FrameList.InsertFreeFrame(frame);
			hRes = GetFrameFullSizeDX8(lockedSrcRect, frame);
			
			if (m_pSurfTemp)
			{
				m_pSurfTemp->UnlockRect();
			}
			if(pBackBuffer) pBackBuffer->Release();
			return 0;
		}
	}
	return 0;
}
2012-2-23 20:01
0
雪    币: 242
活跃值: (443)
能力值: ( LV11,RANK:188 )
在线值:
发帖
回帖
粉丝
5
LS的方法不错,创建一个自己的surface,然后让DX把内容复制过来,再锁自己的surface来操作,应当会有所改观
2012-2-24 00:32
0
雪    币: 773
活跃值: (442)
能力值: ( LV9,RANK:200 )
在线值:
发帖
回帖
粉丝
6
我这个是HOOK DDRAW BLT 虚函数,同时无法创建 另一个LPDIRECTDRAWSURFACE7,因为游戏初始化的时候已经设定好了,hook CreateSurface 都没有反映,要是那样的就的DLL劫持了,经过分析 只要的情况是我现在复制的是 显存所以才操作慢,真是头晕呀,有啥好办法
2012-2-24 08:09
0
雪    币: 773
活跃值: (442)
能力值: ( LV9,RANK:200 )
在线值:
发帖
回帖
粉丝
7
dxd8 我早以实现,exile兄弟,hRes = pDevice->CopyRects(pBackBuffer, &Rect, 1, m_pSurfTemp, points);
copyrects 在有些游戏会复制失败的。武林那个GAME就无法复制surface成功,其他的我还真没找到DX8的游戏
2012-2-24 08:13
0
雪    币: 2105
活跃值: (424)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
8
武林外传?。
2012-2-24 09:10
0
雪    币: 773
活跃值: (442)
能力值: ( LV9,RANK:200 )
在线值:
发帖
回帖
粉丝
9
嗯是呀 武林 用 CopyRects 把 后台缓冲 复制到 imagesurface 会失败
2012-2-24 09:29
0
游客
登录 | 注册 方可回帖
返回
//