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.

256 lines
11 KiB

  1. /****************************************************************************/
  2. // nsbcinl.h
  3. //
  4. // SBC inline functions
  5. //
  6. // Copyright(C) Microsoft Corporation 1997-1999
  7. /****************************************************************************/
  8. #ifndef _H_NSBCINL
  9. #define _H_NSBCINL
  10. #include <nsbcdisp.h>
  11. #define DC_INCLUDE_DATA
  12. #include <nsbcddat.c>
  13. #undef DC_INCLUDE_DATA
  14. /****************************************************************************/
  15. /* Name: SBC_PaletteChanged */
  16. /* */
  17. /* Purpose: Called when the palette changes. */
  18. /****************************************************************************/
  19. __inline void RDPCALL SBC_PaletteChanged(void)
  20. {
  21. sbcPaletteChanged = TRUE;
  22. }
  23. /****************************************************************************/
  24. // SBC_DDIsMemScreenBltCachable
  25. //
  26. // Checks the bitmap format for characteristics that make it uncachable.
  27. // At this point no bitmaps are uncachable since we handle both RLE-encoded
  28. // and regular bitmaps. For RLE bitmaps containing relative-motion deltas
  29. // we have to set up a special flag which is used at the tile level to cause
  30. // us to grab the background screen bits before blt-ing the RLE bitmap over
  31. // them. We also prescan for non-delta RLEs which can be cached normally.
  32. // See MSDN query on "Bitmap Compression" for details on RLE encoding, and
  33. // see comments below.
  34. /****************************************************************************/
  35. __inline BOOLEAN RDPCALL SBC_DDIsMemScreenBltCachable(
  36. PMEMBLT_ORDER_EXTRA_INFO pMemBltInfo)
  37. {
  38. BOOLEAN rc = TRUE;
  39. SURFOBJ *pSourceSurf;
  40. DC_BEGIN_FN("SBC_DDIsMemScreenBltCachable");
  41. if (sbcEnabled & SBC_BITMAP_CACHE_ENABLED) {
  42. pSourceSurf = pMemBltInfo->pSource;
  43. // Tune for the normal case.
  44. if (pSourceSurf->iBitmapFormat != BMF_4RLE &&
  45. pSourceSurf->iBitmapFormat != BMF_8RLE) {
  46. // Reset the RLE flag.
  47. pMemBltInfo->bDeltaRLE = FALSE;
  48. }
  49. else {
  50. BYTE *pBits = (BYTE *)pSourceSurf->pvBits;
  51. BYTE *pEnd = (BYTE *)pSourceSurf->pvBits + pSourceSurf->cjBits - 1;
  52. BYTE RLEDivisor, RLECeilAdjustment;
  53. int PixelsInLine, LinesInBitmap;
  54. TRC_ASSERT((((UINT_PTR)pBits & 1) == 0),
  55. (TB,"Bitmap source address not word aligned!"));
  56. TRC_NRM((TB,"RLE%c, sizl=(%u, %u)", (pSourceSurf->iBitmapFormat ==
  57. BMF_4RLE ? '4' : '8'), pSourceSurf->sizlBitmap.cx,
  58. pSourceSurf->sizlBitmap.cy));
  59. if (pSourceSurf->iBitmapFormat == BMF_8RLE) {
  60. RLEDivisor = 1;
  61. RLECeilAdjustment = 0;
  62. }
  63. else {
  64. RLEDivisor = 2;
  65. RLECeilAdjustment = 1;
  66. }
  67. // Detect offset drawing in bitmap. If offsets are used the bitmap
  68. // cannot be encoded as a regular bitmap since the offsets require
  69. // knowing the screen bits behind the bitmap.
  70. // Note this search is expensive, but since RLE bitmaps are rare
  71. // this is an unusual case. Also note that pEnd is at one less
  72. // than the last byte of the bitmap since all RLE codes are in 2
  73. // byte increments and we scan ahead one byte during loop.
  74. pMemBltInfo->bDeltaRLE = FALSE;
  75. PixelsInLine = 0;
  76. LinesInBitmap = 1;
  77. while (pBits < pEnd) {
  78. if (*pBits == 0x00) {
  79. // 0x00 is an escape. Check the next byte for the action:
  80. // 0x00 means end-of-line
  81. // 0x01 means end-of-bitmap
  82. // 0x02 means delta movement to draw next bits.
  83. // x,y offsets are in 2 bytes after 0x02 code.
  84. // This is the type of encoding we cannot handle.
  85. // 0x03..0xFF means there are this many raw indices
  86. // following. For 4BPP there are 2 indices per
  87. // byte. In both RLE types the run must be padded
  88. // to word alignment relative to the start of the
  89. // bitmap bits.
  90. if (*(pBits + 1) == 0x00) {
  91. // Check that the entire line was drawn in the bitmap.
  92. // Skipping any part of a line means we need to grab
  93. // screen data as a backdrop.
  94. if (PixelsInLine < pSourceSurf->sizlBitmap.cx) {
  95. pMemBltInfo->bDeltaRLE = TRUE;
  96. TRC_NRM((TB,"EOL too soon at %p", pBits));
  97. break;
  98. }
  99. PixelsInLine = 0;
  100. pBits += 2;
  101. LinesInBitmap++;
  102. }
  103. if (*(pBits + 1) == 0x01) {
  104. // Check that the last line was covered (see EOL
  105. // above).
  106. if (PixelsInLine < pSourceSurf->sizlBitmap.cx) {
  107. pMemBltInfo->bDeltaRLE = TRUE;
  108. TRC_NRM((TB,"EOL too soon (EOBitmap) at %p",
  109. pBits));
  110. }
  111. // Check that all lines were covered.
  112. if (LinesInBitmap < pSourceSurf->sizlBitmap.cy) {
  113. pMemBltInfo->bDeltaRLE = TRUE;
  114. TRC_NRM((TB,"EOBitmap too soon not all lines "
  115. "covered at %p", pBits));
  116. }
  117. break;
  118. }
  119. if (*(pBits + 1) == 0x02) {
  120. TRC_NRM((TB,"Delta at %p\n", pBits));
  121. pMemBltInfo->bDeltaRLE = TRUE;
  122. break;
  123. }
  124. else {
  125. PixelsInLine += *(pBits + 1);
  126. if (PixelsInLine > pSourceSurf->sizlBitmap.cx) {
  127. // Implicit wraparound.
  128. TRC_NRM((TB,"Implicit wraparound at %p", pBits));
  129. LinesInBitmap += PixelsInLine / pSourceSurf->
  130. sizlBitmap.cx;
  131. PixelsInLine %= pSourceSurf->sizlBitmap.cx;
  132. }
  133. // Skip the 2 bytes for 0x00 and the number of entries,
  134. // plus #entries bytes for RLE8 (RLEDivisor == 1) or
  135. // ceil(#entries / 2) for RLE4 (RLEDivisor == 2).
  136. pBits += 2 + (*(pBits + 1) + RLECeilAdjustment) /
  137. RLEDivisor;
  138. // Adjust the new pBits for word alignment relative to
  139. // the start of the bitmap. We assume that the
  140. // start addr of the bitmap is word-aligned in memory.
  141. pBits += ((UINT_PTR)pBits & 1);
  142. }
  143. }
  144. else {
  145. // Non-escape count byte, skip it and the next byte
  146. // containing palette indices.
  147. PixelsInLine += *pBits;
  148. if (PixelsInLine > pSourceSurf->sizlBitmap.cx) {
  149. // Implicit wraparound.
  150. TRC_NRM((TB,"Implicit wraparound at %p", pBits));
  151. LinesInBitmap += PixelsInLine / pSourceSurf->
  152. sizlBitmap.cx;
  153. PixelsInLine %= pSourceSurf->sizlBitmap.cx;
  154. }
  155. pBits += 2;
  156. }
  157. }
  158. }
  159. }
  160. else {
  161. rc = FALSE;
  162. TRC_DBG((TB, "Caching not enabled"));
  163. }
  164. DC_END_FN();
  165. return rc;
  166. }
  167. /****************************************************************************/
  168. // SBC_DDQueryBitmapTileSize
  169. //
  170. // Returns the tile size to use for a given bitblt on a given bitmap.
  171. /****************************************************************************/
  172. __inline unsigned SBC_DDQueryBitmapTileSize(
  173. unsigned bmpWidth,
  174. unsigned bmpHeight,
  175. PPOINTL pptlSrc,
  176. unsigned width,
  177. unsigned height)
  178. {
  179. unsigned i;
  180. unsigned TileSize;
  181. DC_BEGIN_FN("SBC_DDQueryBitmapTileSize");
  182. // We should have at least one functional cache or this will go badly.
  183. TRC_ASSERT((pddShm->sbc.NumBitmapCaches > 0),(TB,"No bitmap caches"));
  184. // Loop through all sizes seeing if the src rect start is a multiple of the
  185. // tile dimension, the blt size is not bigger than the tile size, and
  186. // there are an integral number of tiles in the blt. If this matches
  187. // anywhere we have our tile size. Don't check the last tile size since
  188. // that's a default anyway.
  189. for (i = 0; i < pddShm->sbc.NumBitmapCaches; i++) {
  190. TileSize = SBC_CACHE_0_DIMENSION << i;
  191. if ((((pptlSrc->x & (TileSize - 1)) == 0) &&
  192. ((pptlSrc->y & (TileSize - 1)) == 0) &&
  193. (width <= TileSize) &&
  194. (height <= TileSize)) ||
  195. ((((unsigned)pptlSrc->x >> (SBC_CACHE_0_DIMENSION_SHIFT + i)) ==
  196. (((unsigned)pptlSrc->x + width - 1) >>
  197. (SBC_CACHE_0_DIMENSION_SHIFT + i))) &&
  198. (((unsigned)pptlSrc->y >> (SBC_CACHE_0_DIMENSION_SHIFT + i)) ==
  199. (((unsigned)pptlSrc->y + height - 1) >>
  200. (SBC_CACHE_0_DIMENSION_SHIFT + i))))) {
  201. goto EndFunc;
  202. }
  203. }
  204. // Cycle through the caches, checking for if the bitmap will fit
  205. // into a tile size in one of its dimensions. Don't check the
  206. // last size since that's the default if no others work.
  207. for (i = 0; i < (pddShm->sbc.NumBitmapCaches - 1); i++) {
  208. //TODO: What about using 'or' here -- uses more of smaller tiles when
  209. // one dimension is bad. But could send more data.
  210. if (bmpWidth <= (unsigned)(SBC_CACHE_0_DIMENSION << i) &&
  211. bmpHeight <= (unsigned)(SBC_CACHE_0_DIMENSION << i))
  212. break;
  213. }
  214. EndFunc:
  215. TRC_NRM((TB, "Tile(%u x %u, TileID %d) bmpWidth(%u) bmpHeight(%u)"
  216. "srcLeft(%d) srcTop(%d) width(%d) height(%d)",
  217. (SBC_CACHE_0_DIMENSION << i), (SBC_CACHE_0_DIMENSION << i),
  218. i, bmpWidth, bmpHeight, pptlSrc->x, pptlSrc->y, width,
  219. height));
  220. DC_END_FN();
  221. return i;
  222. }
  223. #endif /* _H_NSBCINL */