- Implement batching for DeleteObject.

- Implemented DeleteRegion, a support function with batching.
- Add delete objects and a hack to fake the running of the batch to gdibatch.c.
- These batching functions will not run until proper structure attributes are implemented.

svn path=/trunk/; revision=30144
This commit is contained in:
James Tabor 2007-11-05 01:50:59 +00:00
parent ca76afe698
commit 1423476391
4 changed files with 87 additions and 5 deletions

View file

@ -112,6 +112,10 @@ NewTextMetricExW2A(
NEWTEXTMETRICEXW *tmw NEWTEXTMETRICEXW *tmw
); );
BOOL
FASTCALL
DeleteRegion( HRGN );
BOOL BOOL
GdiIsHandleValid(HGDIOBJ hGdiObj); GdiIsHandleValid(HGDIOBJ hGdiObj);

View file

@ -284,7 +284,7 @@ STDCALL
DeleteObject(HGDIOBJ hObject) DeleteObject(HGDIOBJ hObject)
{ {
UINT Type = 0; UINT Type = 0;
/* From Wine: DeleteObject does not SetLastError() on a null object */ /* From Wine: DeleteObject does not SetLastError() on a null object */
if(!hObject) return FALSE; if(!hObject) return FALSE;
@ -308,6 +308,8 @@ DeleteObject(HGDIOBJ hObject)
return DeleteDC((HDC) hObject); return DeleteDC((HDC) hObject);
case GDI_OBJECT_TYPE_COLORSPACE: case GDI_OBJECT_TYPE_COLORSPACE:
return NtGdiDeleteColorSpace((HCOLORSPACE) hObject); return NtGdiDeleteColorSpace((HCOLORSPACE) hObject);
case GDI_OBJECT_TYPE_REGION:
return DeleteRegion((HRGN) hObject);
#if 0 #if 0
case GDI_OBJECT_TYPE_METADC: case GDI_OBJECT_TYPE_METADC:
return MFDRV_DeleteObject( hObject ); return MFDRV_DeleteObject( hObject );
@ -318,12 +320,42 @@ DeleteObject(HGDIOBJ hObject)
return EMFDRV_DeleteObject( hObject ); return EMFDRV_DeleteObject( hObject );
} }
#endif #endif
case GDI_OBJECT_TYPE_REGION: case GDI_OBJECT_TYPE_FONT:
break;
case GDI_OBJECT_TYPE_BRUSH: case GDI_OBJECT_TYPE_BRUSH:
case GDI_OBJECT_TYPE_EXTPEN: case GDI_OBJECT_TYPE_EXTPEN:
case GDI_OBJECT_TYPE_PEN: case GDI_OBJECT_TYPE_PEN:
case GDI_OBJECT_TYPE_FONT: {
#if 0
PBRUSH_ATTR Brh_Attr;
PTEB pTeb;
if ((!GdiGetHandleUserData(hObject, (PVOID) &Brh_Attr)) ||
(Brh_Attr == NULL) ) break;
pTeb = NtCurrentTeb();
if (pTeb->Win32ThreadInfo == NULL) break;
if ((pTeb->GdiTebBatch.Offset + sizeof(GDIBSOBJECT)) <= GDIBATCHBUFSIZE)
{
PGDIBSOBJECT pgO = (PGDIBSOBJECT)(&pTeb->GdiTebBatch.Buffer[0] +
pTeb->GdiTebBatch.Offset);
pgO->gbHdr.Cmd = GdiBCDelObj;
pgO->gbHdr.Size = sizeof(GDIBSOBJECT);
pgO->hgdiobj = hObject;
pTeb->GdiTebBatch.Offset += sizeof(GDIBSSETBRHORG);
pTeb->GdiBatchCount++;
if (pTeb->GdiBatchCount >= GDI_BatchLimit) NtGdiFlush();
return TRUE;
}
#endif
break;
}
case GDI_OBJECT_TYPE_BITMAP: case GDI_OBJECT_TYPE_BITMAP:
default:
break; break;
} }
return NtGdiDeleteObjectApp(hObject); return NtGdiDeleteObjectApp(hObject);

View file

@ -76,3 +76,40 @@ CreateRectRgnIndirect(
return CreateRectRgn(prc->left, prc->top, prc->right, prc->bottom); return CreateRectRgn(prc->left, prc->top, prc->right, prc->bottom);
} }
/*
* I thought it was okay to have this in DeleteObject but~ Speed. (jt)
*/
BOOL
FASTCALL
DeleteRegion( HRGN hRgn )
{
#if 0
PREGION_ATTR Rgn_Attr;
if ((GdiGetHandleUserData((HGDIOBJ) hRgn, (PVOID) &Rgn_Attr)) &&
( Rgn_Attr != NULL ))
{
PTEB pTeb = NtCurrentTeb();
if (pTeb->Win32ThreadInfo != NULL)
{
if ((pTeb->GdiTebBatch.Offset + sizeof(GDIBSOBJECT)) <= GDIBATCHBUFSIZE)
{
PGDIBSOBJECT pgO = (PGDIBSOBJECT)(&pTeb->GdiTebBatch.Buffer[0] +
pTeb->GdiTebBatch.Offset);
pgO->gbHdr.Cmd = GdiBCDelRgn;
pgO->gbHdr.Size = sizeof(GDIBSOBJECT);
pgO->hgdiobj = (HGDIOBJ)hRgn;
pTeb->GdiTebBatch.Offset += sizeof(GDIBSSETBRHORG);
pTeb->GdiBatchCount++;
if (pTeb->GdiBatchCount >= GDI_BatchLimit) NtGdiFlush();
return TRUE;
}
}
}
#endif
return NtGdiDeleteObjectApp((HGDIOBJ) hRgn);
}

View file

@ -42,9 +42,12 @@ GdiFlushUserBatch(HDC hDC, PGDIBATCHHDR pHdr)
case GdiBCSelObj: case GdiBCSelObj:
break; break;
case GdiBCDelObj: case GdiBCDelObj:
break;
case GdiBCDelRgn: case GdiBCDelRgn:
{
PGDIBSOBJECT pgO = (PGDIBSOBJECT) pHdr;
NtGdiDeleteObject( pgO->hgdiobj );
break; break;
}
default: default:
DC_UnlockDc(dc); DC_UnlockDc(dc);
return 0; return 0;
@ -62,6 +65,8 @@ VOID
APIENTRY APIENTRY
NtGdiFlush(VOID) NtGdiFlush(VOID)
{ {
// Hack! FIXME!
NtYieldExecution(); // Force thread to sunset and run the flush.
UNIMPLEMENTED; UNIMPLEMENTED;
} }
@ -82,7 +87,11 @@ NtGdiFlushUserBatch(VOID)
if( (GdiBatchCount > 0) && (GdiBatchCount <= GDIBATCHBUFSIZE)) if( (GdiBatchCount > 0) && (GdiBatchCount <= GDIBATCHBUFSIZE))
{ {
HDC hDC = (HDC) pTeb->GdiTebBatch.HDC; HDC hDC = (HDC) pTeb->GdiTebBatch.HDC;
if (hDC) //
// If hDC is zero and the buffer fills up with delete objects we need to run
// anyway. So, hard code to the system batch limit.
//
if ((hDC) || (GdiBatchCount >= GDI_BATCH_LIMIT))
{ {
PULONG pHdr = &pTeb->GdiTebBatch.Buffer[0]; PULONG pHdr = &pTeb->GdiTebBatch.Buffer[0];
// No need to init anything, just go! // No need to init anything, just go!