Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

139 lines
4.7 KiB

  1. /******************************Module*Header**********************************\
  2. *
  3. * *******************
  4. * * GDI SAMPLE CODE *
  5. * *******************
  6. *
  7. * Module Name: sync.c
  8. *
  9. * Surface synchronization support.
  10. *
  11. * Copyright (c) 1994-1998 3Dlabs Inc. Ltd. All rights reserved.
  12. * Copyright (c) 1995-1999 Microsoft Corporation. All rights reserved.
  13. \*****************************************************************************/
  14. #include "precomp.h"
  15. #include "gdi.h"
  16. //-----------------------------Public*Routine----------------------------------
  17. //
  18. // VOID DrvSynchronizeSurface(pso, prcl, fl)
  19. //
  20. // DrvSynchronizeSurface allows drawing operations performed on the specified
  21. // surface by a device's coprocessor to be coordinated with GDI.
  22. //
  23. // Parameters
  24. // pso---------Points to a SURFOBJ that identifies the surface on which the
  25. // drawing synchronization is to occur.
  26. // prcl--------Specifies a rectangle on the surface that GDI will draw into, or
  27. // NULL. If this does not collide with the drawing operation in
  28. // progress, the driver can elect to let GDI draw without waiting
  29. // for the coprocessor to complete.
  30. // fl----------Flag
  31. //
  32. // Comments
  33. // DrvSynchronize can be optionally implemented in graphics drivers. It is
  34. // intended to support devices that use a coprocessor for drawing. Such a
  35. // device can start a long drawing operation and return to GDI while the
  36. // operation continues. If the device driver does not perform all drawing
  37. // operations to the surface, it is possible that a subsequent drawing
  38. // operation will be handled by GDI. In this case, it is necessary for GDI
  39. // to wait for the coprocessor to complete its work before drawing on the
  40. // surface. DrvSynchronize is not an output function.
  41. //
  42. // This function is only called if it is hooked by EngAssociateSurface.
  43. // GDI will call DrvSynchronizeSurface()
  44. // 1. before rendering to any device managed surface
  45. // 2. when at timer event occurs and GCAPS2_SYNCTIMER was specified passing
  46. // the desktop surface and specifying DSS_TIMER_EVENT
  47. // 3. when a flush evern occurs and GCAPS2_SYNCFLUSH was specified passing
  48. // the desktip surface and specifying DSS_FLUSH_EVENT
  49. //
  50. // The function should return when it is safe for GDI to draw on the surface.
  51. //
  52. // Per surface synchronization enables hardware which uses a graphics
  53. // acceleration queue model to flush the acceleration queue only to the extent
  54. // that is neccessary. That is, it only has to flush up to the last
  55. // queue entry that references the given surface.
  56. //
  57. // GDI will call DrvSynchronizeSurface instead of DrvSynchronize in drivers
  58. // that implement both of these functions. DrvSynchronize is called (and
  59. // shouuld be provided) only if DrvSyncrhoizeSurface is not provided.
  60. //
  61. //-----------------------------------------------------------------------------
  62. VOID
  63. DrvSynchronizeSurface(SURFOBJ* pso,
  64. RECTL* prcl,
  65. FLONG fl)
  66. {
  67. Surf *psurf;
  68. PDev *ppdev = (PDev *) pso->dhpdev;
  69. ASSERTDD(pso->dhsurf != NULL,
  70. "DrvSynchronizeSurface: called with GDI managed surface");
  71. //@@BEGIN_DDKSPLIT
  72. #if MULTITHREADED
  73. if(ppdev->ulLockCount)
  74. {
  75. DBG_GDI((MT_LOG_LEVEL, "DrvSynchronizeSurface: re-entered! %d", ppdev->ulLockCount));
  76. }
  77. EngAcquireSemaphore(ppdev->hsemLock);
  78. ppdev->ulLockCount++;
  79. #endif
  80. //@@END_DDKSPLIT
  81. psurf = (Surf *) pso->dhsurf;
  82. if ( fl & (DSS_FLUSH_EVENT | DSS_TIMER_EVENT) )
  83. {
  84. if(ppdev->bGdiContext && ppdev->bNeedSync)
  85. {
  86. if(ppdev->bForceSwap)
  87. {
  88. ppdev->bForceSwap = FALSE;
  89. InputBufferSwap(ppdev);
  90. }
  91. else
  92. InputBufferFlush(ppdev);
  93. }
  94. goto done;
  95. }
  96. else if ( psurf->flags & SF_VM )
  97. {
  98. // If we only had a hardware acceleration queue with per surface
  99. // reference counting perhaps we could sync to this passed in surface
  100. // for now just fall through to below
  101. }
  102. // we don't have per surface synchronization ... always sync the entire
  103. // dma buffer
  104. if(ppdev->bGdiContext)
  105. {
  106. InputBufferSync(ppdev);
  107. }
  108. else
  109. {
  110. //@@BEGIN_DDKSPLIT
  111. #if MULTITHREADED && DBG
  112. ppdev->pP2dma->ppdev = ppdev;
  113. #endif
  114. //@@END_DDKSPLIT
  115. vSyncWithPermedia(ppdev->pP2dma);
  116. }
  117. done:
  118. //@@BEGIN_DDKSPLIT
  119. #if MULTITHREADED
  120. ppdev->ulLockCount--;
  121. EngReleaseSemaphore(ppdev->hsemLock);
  122. #endif
  123. //@@END_DDKSPLIT
  124. return;
  125. }