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.

2357 lines
75 KiB

  1. #include "precomp.h"
  2. //
  3. // SBC.CPP
  4. // Send Bitmap Cache
  5. //
  6. // Copyright(c) Microsoft 1997-
  7. //
  8. #define MLZ_FILE_ZONE ZONE_CORE
  9. //
  10. // SBC_HostStarting()
  11. //
  12. BOOL ASHost::SBC_HostStarting(void)
  13. {
  14. BITMAPINFO_ours bitmapInfo;
  15. int i;
  16. BOOL rc = FALSE;
  17. DebugEntry(ASHost::SBC_HostStarting);
  18. if (g_sbcEnabled)
  19. {
  20. //
  21. // We create a DIB section for each tile size which we use during the
  22. // conversion of a bitmap from the native (device) bpp to the protocol
  23. // bpp. We create the DIB sections at the device bpp.
  24. //
  25. ZeroMemory(&bitmapInfo, sizeof(bitmapInfo));
  26. m_pShare->USR_InitDIBitmapHeader((BITMAPINFOHEADER *)&bitmapInfo, g_usrCaptureBPP);
  27. // We only capture at 8 or 24 for NT 5.0, otherwise the screen depth
  28. if ((g_usrCaptureBPP > 8) && (g_usrCaptureBPP != 24))
  29. {
  30. //
  31. // If the device bpp is > 8 (but not 24), we have to set up the DIB
  32. // section to use the same bitmasks as the device. This means
  33. // setting the compression type to BI_BITFIELDS and setting the
  34. // first 3 DWORDS of the bitmap info color table to be the bitmasks
  35. // for R, G and B respectively.
  36. //
  37. // 24bpp does not use bitmasks - it must use
  38. // regular BI_RGB format with 8 bits for each colour.
  39. //
  40. bitmapInfo.bmiHeader.biCompression = BI_BITFIELDS;
  41. ASSERT(g_asbcBitMasks[0]);
  42. ASSERT(g_asbcBitMasks[1]);
  43. ASSERT(g_asbcBitMasks[2]);
  44. bitmapInfo.bmiColors[0] = ((LPTSHR_RGBQUAD)g_asbcBitMasks)[0];
  45. bitmapInfo.bmiColors[1] = ((LPTSHR_RGBQUAD)g_asbcBitMasks)[1];
  46. bitmapInfo.bmiColors[2] = ((LPTSHR_RGBQUAD)g_asbcBitMasks)[2];
  47. }
  48. //
  49. // Initialize m_asbcWorkInfo array which holds the info we use to
  50. // convert from native bpp to protocol bpp.
  51. //
  52. //
  53. // First, intialize all the fields to default values
  54. //
  55. for (i = 0; i < SBC_NUM_TILE_SIZES ; i++)
  56. {
  57. ASSERT(!m_asbcWorkInfo[i].pShuntBuffer);
  58. ASSERT(g_asbcShuntBuffers[i]);
  59. m_asbcWorkInfo[i].pShuntBuffer = g_asbcShuntBuffers[i];
  60. ASSERT(m_asbcWorkInfo[i].mruIndex == 0);
  61. ASSERT(m_asbcWorkInfo[i].workBitmap == 0);
  62. ASSERT(m_asbcWorkInfo[i].pWorkBitmapBits == NULL);
  63. if (i == SBC_MEDIUM_TILE_INDEX)
  64. {
  65. m_asbcWorkInfo[i].tileWidth = MP_MEDIUM_TILE_WIDTH;
  66. m_asbcWorkInfo[i].tileHeight = MP_MEDIUM_TILE_HEIGHT;
  67. }
  68. else
  69. {
  70. m_asbcWorkInfo[i].tileWidth = MP_LARGE_TILE_WIDTH;
  71. m_asbcWorkInfo[i].tileHeight = MP_LARGE_TILE_HEIGHT;
  72. }
  73. bitmapInfo.bmiHeader.biWidth = m_asbcWorkInfo[i].tileWidth;
  74. bitmapInfo.bmiHeader.biHeight = m_asbcWorkInfo[i].tileHeight;
  75. m_asbcWorkInfo[i].workBitmap = CreateDIBSection(NULL,
  76. (BITMAPINFO*)&bitmapInfo,
  77. DIB_RGB_COLORS,
  78. (void **)&(m_asbcWorkInfo[i].pWorkBitmapBits),
  79. NULL, // File mapping object
  80. 0); // Offset into file
  81. // mapping object
  82. if (!m_asbcWorkInfo[i].workBitmap)
  83. {
  84. ERROR_OUT(("Failed to create SBC DIB section %d", i));
  85. DC_QUIT;
  86. }
  87. ASSERT(m_asbcWorkInfo[i].pWorkBitmapBits);
  88. TRACE_OUT(( "Created work DIB section %d, pBits = 0x%08x",
  89. i, m_asbcWorkInfo[i].pWorkBitmapBits));
  90. }
  91. //
  92. // Initialize the fastpath
  93. //
  94. if (!SBCInitFastPath())
  95. {
  96. TRACE_OUT(( "Failed to init fastpath"));
  97. DC_QUIT;
  98. }
  99. if (!SBCInitInternalOrders())
  100. {
  101. ERROR_OUT(( "Failed to init SBC internal order struct"));
  102. DC_QUIT;
  103. }
  104. m_pShare->SBC_RecalcCaps(TRUE);
  105. }
  106. rc = TRUE;
  107. DC_EXIT_POINT:
  108. DebugExitBOOL(ASHost::SBC_HostStarting, rc);
  109. return(rc);
  110. }
  111. //
  112. // ASShare::SBC_HostEnded()
  113. //
  114. void ASHost::SBC_HostEnded(void)
  115. {
  116. int i;
  117. DebugEntry(ASHost::SBC_HostEnded);
  118. if (g_sbcEnabled)
  119. {
  120. //
  121. // Free up the memory associated with sbcOrderInfo.
  122. //
  123. SBCFreeInternalOrders();
  124. SBCInitCacheStructures();
  125. //
  126. // Free our fast path info
  127. //
  128. if (m_sbcFastPath)
  129. {
  130. delete m_sbcFastPath;
  131. m_sbcFastPath = NULL;
  132. }
  133. //
  134. // Clear our cache handles.
  135. //
  136. for (i = 0; i < NUM_BMP_CACHES; i++)
  137. {
  138. if (m_asbcBmpCaches[i].handle != 0)
  139. {
  140. TRACE_OUT(( "Clear cache %d", i));
  141. CH_DestroyCache(m_asbcBmpCaches[i].handle);
  142. BMCFreeCacheData(&m_asbcBmpCaches[i]);
  143. }
  144. }
  145. //
  146. // Free our work DIB sections
  147. //
  148. //
  149. // We just have to delete the DIB sections and reset our variables.
  150. //
  151. for (i = 0 ; i < SBC_NUM_TILE_SIZES ; i++)
  152. {
  153. m_asbcWorkInfo[i].pShuntBuffer = NULL;
  154. if (m_asbcWorkInfo[i].workBitmap != NULL)
  155. {
  156. DeleteBitmap(m_asbcWorkInfo[i].workBitmap);
  157. m_asbcWorkInfo[i].workBitmap = NULL;
  158. m_asbcWorkInfo[i].pWorkBitmapBits = NULL;
  159. }
  160. }
  161. }
  162. DebugExitVOID(ASHost::SBC_HostEnded);
  163. }
  164. //
  165. // SBC_SyncOutgoing()
  166. // Called when we're already hosting and someone new joins the share.
  167. // Resets the OUTGOING bitmap cache for bitblt orders.
  168. //
  169. void ASHost::SBC_SyncOutgoing(void)
  170. {
  171. int i;
  172. DebugEntry(ASHost::SBC_SyncOutgoing);
  173. //
  174. // Only do anything if SBC is enabled
  175. //
  176. if (g_sbcEnabled)
  177. {
  178. //
  179. // Discard all currently cached bitmaps and set the colour table to
  180. // zero so that the next bitmap order which arrives will trigger the
  181. // sending of a new colour table first. Note that if the colour table
  182. // is then full of zeros(!) it will still be OK because the RBC zeros
  183. // out its copy of the colour table when a new host joins the share.
  184. //
  185. TRACE_OUT(( "Clearing all send caches"));
  186. SBCInitCacheStructures();
  187. //
  188. // All we have to do here is to reset our MRU indices for each of the
  189. // shunt buffers. Each of the entries in the shunt buffer will be
  190. // marked as free down in the driver.
  191. //
  192. for (i = 0; i < SBC_NUM_TILE_SIZES; i++)
  193. {
  194. m_asbcWorkInfo[i].mruIndex = 0;
  195. }
  196. }
  197. DebugExitVOID(ASHost::SBC_SyncOutgoing);
  198. }
  199. //
  200. //
  201. // SBC_CopyPrivateOrderData()
  202. //
  203. //
  204. UINT ASHost::SBC_CopyPrivateOrderData
  205. (
  206. LPBYTE pDst,
  207. LPCOM_ORDER pOrder,
  208. UINT freeBytesInBuffer
  209. )
  210. {
  211. UINT orderSize;
  212. LPBYTE pBitmapBits;
  213. DebugEntry(ASHost::SBC_CopyPrivateOrderData);
  214. //
  215. // Copy the order header without the rectangle structure (which we
  216. // do not use).
  217. //
  218. orderSize = sizeof(pOrder->OrderHeader)
  219. - sizeof(pOrder->OrderHeader.rcsDst);
  220. memcpy(pDst, pOrder, orderSize);
  221. //
  222. // Copy the basic order data.
  223. //
  224. memcpy(pDst + orderSize,
  225. pOrder->abOrderData,
  226. pOrder->OrderHeader.cbOrderDataLength);
  227. orderSize += pOrder->OrderHeader.cbOrderDataLength;
  228. if (orderSize > freeBytesInBuffer)
  229. {
  230. ERROR_OUT(( "Overwritten end of buffer. (%u) > (%u)",
  231. orderSize,
  232. freeBytesInBuffer));
  233. }
  234. //
  235. // Set the length field in the order header to be the total amount of
  236. // data we have copied (including the partial header) minus the
  237. // size of a full header. This is horrible! - but is needed because
  238. // the OD2 code looks at the header (which it really should not know
  239. // about) and uses the length field to calculate the total length of
  240. // the order. The OD2 code does not know that we have omitted some
  241. // of the header.
  242. //
  243. ((LPCOM_ORDER)pDst)->OrderHeader.cbOrderDataLength =
  244. (WORD)(orderSize - sizeof(COM_ORDER_HEADER));
  245. //
  246. // Return the total number of bytes that we have copied.
  247. //
  248. DebugExitDWORD(ASHost::SBC_CopyPrivateOrderData, orderSize);
  249. return(orderSize);
  250. }
  251. //
  252. // Name: SBCInitCacheStructures()
  253. //
  254. // Purpose:
  255. //
  256. // Returns:
  257. //
  258. // Params:
  259. //
  260. // Operation:
  261. //
  262. //
  263. void ASHost::SBCInitCacheStructures(void)
  264. {
  265. UINT i;
  266. DebugEntry(ASHost::SBCInitCacheStructures);
  267. ASSERT(g_sbcEnabled);
  268. //
  269. // Reset caches
  270. //
  271. for (i = 0; i < NUM_BMP_CACHES; i++)
  272. {
  273. if (m_asbcBmpCaches[i].handle)
  274. {
  275. CH_ClearCache(m_asbcBmpCaches[i].handle);
  276. }
  277. }
  278. //
  279. // Do any OS specific processing
  280. //
  281. SBC_CacheCleared();
  282. DebugExitVOID(ASHost::SBCInitCacheStructures);
  283. }
  284. //
  285. // SBC_CacheCleared()
  286. //
  287. void ASHost::SBC_CacheCleared(void)
  288. {
  289. int i;
  290. DebugEntry(ASHost::SBC_CacheCleared);
  291. ASSERT(g_sbcEnabled);
  292. ASSERT(m_sbcFastPath);
  293. //
  294. // The cache has been cleared. Reset our fast path.
  295. //
  296. COM_BasedListInit(&m_sbcFastPath->usedList);
  297. COM_BasedListInit(&m_sbcFastPath->freeList);
  298. for (i = 0; i < SBC_FASTPATH_ENTRIES; i++)
  299. {
  300. m_sbcFastPath->entry[i].list.next = 0;
  301. m_sbcFastPath->entry[i].list.prev = 0;
  302. COM_BasedListInsertBefore(&m_sbcFastPath->freeList,
  303. &m_sbcFastPath->entry[i].list);
  304. }
  305. DebugExitVOID(ASHost::SBC_CacheCleared);
  306. }
  307. //
  308. //
  309. // SBCSelectCache(..)
  310. //
  311. // Decides which cache a sub-bitmap from a source bitmap of the specified
  312. // size should go in.
  313. //
  314. // To be cached, the sub-bitmap must:
  315. // have a size, in compressed bytes, which fits in the cache
  316. //
  317. // The R1.1 cache selection is irrespective of the actual memory
  318. // requirement for the cached data. This is wasteful of space, but is
  319. // necessary for R1.1 compatibility. (The R1.1 cache paremeters mean that
  320. // the total cache will be below about 128K in any case)
  321. //
  322. // For R2.0 the cache is selected by this function by comparing the
  323. // post-compress size with the cell area of each of the caches. This gives
  324. // us a much better space usage on both server and client.
  325. //
  326. // Returns:
  327. // TRUE if the sub-bitmap can be cached.
  328. // *pCache is updated with the index of the selected cache.
  329. //
  330. // FALSE if the sub-bitmap cannot be cached.
  331. // *pCache is not updated.
  332. //
  333. //
  334. BOOL ASHost::SBCSelectCache
  335. (
  336. UINT cSize,
  337. UINT * pCache
  338. )
  339. {
  340. BOOL fCacheSelected;
  341. BOOL fSelectedCacheIsFull;
  342. UINT i;
  343. DebugEntry(ASHost::SBCSelectCache);
  344. fCacheSelected = FALSE;
  345. fSelectedCacheIsFull = FALSE;
  346. //
  347. // This loop makes the assumption that cache 0 is the smallest. If
  348. // abmcint.h changes this assumption it will need rewriting.
  349. //
  350. for (i = 0; i < NUM_BMP_CACHES; i++)
  351. {
  352. if (m_asbcBmpCaches[i].cEntries <= 0)
  353. {
  354. //
  355. // No entries in this cache, so skip to the next one
  356. //
  357. continue;
  358. }
  359. //
  360. // R2 bitmap cache - only consider total cell size.
  361. //
  362. // Only consider this cache if
  363. // - we haven't yet found a cache
  364. // OR
  365. // - we have found a cache, but it is full (i.e. will
  366. // require an entry to be ejected) AND this one is not
  367. // full
  368. //
  369. // (Note that a cache is full if freeEntry != NULL)
  370. //
  371. if (!fCacheSelected ||
  372. (fSelectedCacheIsFull &&
  373. ((m_asbcBmpCaches[i].freeEntry == NULL)
  374. || !m_asbcBmpCaches[i].freeEntry->inUse)))
  375. {
  376. if (cSize <= m_asbcBmpCaches[i].cSize)
  377. {
  378. if (fSelectedCacheIsFull)
  379. {
  380. TRACE_OUT(("Using cache %u because cache %u is full",
  381. *pCache, i));
  382. }
  383. *pCache = i;
  384. fCacheSelected = TRUE;
  385. fSelectedCacheIsFull =
  386. ((m_asbcBmpCaches[i].freeEntry != NULL) &&
  387. m_asbcBmpCaches[i].freeEntry->inUse);
  388. if (!fSelectedCacheIsFull)
  389. {
  390. break;
  391. }
  392. }
  393. }
  394. }
  395. DebugExitDWORD(ASHost::SBCSelectCache, fCacheSelected);
  396. return(fCacheSelected);
  397. }
  398. //
  399. // FUNCTION: SBC_RecreateSendCache
  400. //
  401. // DESCRIPTION:
  402. //
  403. // (Re)creates the send bitmap cache with a size suitable for the current
  404. // capabilities.
  405. //
  406. // PARAMETERS:
  407. // cache - index to the cache being recreated
  408. // cOldEntries - the previous max number of entries in the cache
  409. // oldCellSize - the previous cell size
  410. //
  411. // RETURNS: NONE
  412. //
  413. //
  414. void ASHost::SBC_RecreateSendCache
  415. (
  416. UINT cache,
  417. UINT newNumEntries,
  418. UINT newCellSize
  419. )
  420. {
  421. PBMC_DIB_CACHE pCache = &(m_asbcBmpCaches[cache]);
  422. DebugEntry(ASHost::SBC_RecreateSendCache);
  423. //
  424. // Allocate the memory for the new send cache
  425. //
  426. ASSERT((newCellSize != pCache->cCellSize) ||
  427. (newNumEntries != pCache->cEntries));
  428. //
  429. // If the cache already exists then destroy it first
  430. //
  431. if (pCache->handle != 0)
  432. {
  433. TRACE_OUT(( "Destroy SBC cache %d", cache));
  434. CH_DestroyCache(pCache->handle);
  435. pCache->handle = 0;
  436. }
  437. //
  438. // Now reallocate the cache data. This will free any memory previously
  439. // allocated. If the entries/cellsize is zero, it will return success.
  440. //
  441. if (!BMCAllocateCacheData(newNumEntries, newCellSize, cache, pCache))
  442. {
  443. ERROR_OUT(( "Bitmap caching disabled for cache %u", cache));
  444. }
  445. if (pCache->cEntries > 0)
  446. {
  447. //
  448. // Allocate cache handler cache. Note that we force the cache
  449. // handler to leave us with one entry in our hand at all times by
  450. // decrementing its count of entries.
  451. //
  452. if (!CH_CreateCache(&(pCache->handle),
  453. pCache->cEntries - 1,
  454. SBC_NUM_CATEGORIES,
  455. BMC_DIB_NOT_HASHED,
  456. SBCCacheCallback ))
  457. {
  458. ERROR_OUT(( "Could not allocate SBC cache of (%u)",
  459. pCache->cEntries));
  460. pCache->cEntries = 0;
  461. }
  462. }
  463. TRACE_OUT(( "Created new cache: 0x%08x, size %u",
  464. pCache->handle,
  465. pCache->cEntries));
  466. //
  467. // Copy the relevant cache information into the shared memory buffer
  468. //
  469. m_asbcCacheInfo[cache].cEntries = (WORD)pCache->cEntries;
  470. m_asbcCacheInfo[cache].cCellSize = (WORD)pCache->cCellSize;
  471. TRACE_OUT(("SBC cache %d: %d entries of size %d",
  472. cache, m_asbcCacheInfo[cache].cEntries, m_asbcCacheInfo[cache].cCellSize));
  473. DebugExitVOID(ASHost::SBC_RecreateSendCache);
  474. }
  475. //
  476. // SBC_RecalcCaps()
  477. //
  478. // Enumerates all the people in the share and redetermines the size of the
  479. // bitmap cache depending on their and the local receive capabilities.
  480. //
  481. //
  482. // THIS CAN GO AWAY WHEN 2.X COMPAT DOES
  483. //
  484. void ASShare::SBC_RecalcCaps(BOOL fJoiner)
  485. {
  486. SBC_NEW_CAPABILITIES newCapabilities;
  487. UINT newSmallCellSize;
  488. UINT newSmallMaxEntries;
  489. UINT newMediumCellSize;
  490. UINT newMediumMaxEntries;
  491. UINT newLargeCellSize;
  492. UINT newLargeMaxEntries;
  493. PBMC_DIB_CACHE pSmall;
  494. PBMC_DIB_CACHE pMedium;
  495. PBMC_DIB_CACHE pLarge;
  496. BOOL cacheChanged = FALSE;
  497. ASPerson * pasT;
  498. DebugEntry(ASShare::SBC_RecalcCaps);
  499. if (!m_pHost || !g_sbcEnabled)
  500. {
  501. //
  502. // Nothing to do -- we're not hosting, or there is no SBC. Note that
  503. // 2.x always recalculated this stuff when somebody joined AND
  504. // somebody left.
  505. //
  506. DC_QUIT;
  507. }
  508. ValidatePerson(m_pasLocal);
  509. pSmall = &(m_pHost->m_asbcBmpCaches[ID_SMALL_BMP_CACHE]);
  510. pMedium= &(m_pHost->m_asbcBmpCaches[ID_MEDIUM_BMP_CACHE]);
  511. pLarge = &(m_pHost->m_asbcBmpCaches[ID_LARGE_BMP_CACHE]);
  512. //
  513. // Enumerate all the bitmap cache receive capabilities of the parties
  514. // in the share. The usable size of the send bitmap cache is then the
  515. // minimum of all the remote receive caches and the local send cache
  516. // size.
  517. //
  518. //
  519. // Start by setting the size of the local send bitmap cache to the
  520. // local default values.
  521. //
  522. newSmallCellSize = m_pasLocal->cpcCaps.bitmaps.sender.capsSmallCacheCellSize;
  523. newSmallMaxEntries = m_pasLocal->cpcCaps.bitmaps.sender.capsSmallCacheNumEntries;
  524. newMediumCellSize = m_pasLocal->cpcCaps.bitmaps.sender.capsMediumCacheCellSize;
  525. newMediumMaxEntries = m_pasLocal->cpcCaps.bitmaps.sender.capsMediumCacheNumEntries;
  526. newLargeCellSize = m_pasLocal->cpcCaps.bitmaps.sender.capsLargeCacheCellSize;
  527. newLargeMaxEntries = m_pasLocal->cpcCaps.bitmaps.sender.capsLargeCacheNumEntries;
  528. if (m_scShareVersion < CAPS_VERSION_30)
  529. {
  530. TRACE_OUT(("In share with 2.x nodes, must recalc SBC caps"));
  531. //
  532. // Now enumerate all the REMOTE parties in the share and set our send bitmap
  533. // size appropriately.
  534. //
  535. for (pasT = m_pasLocal->pasNext; pasT != NULL; pasT = pasT->pasNext)
  536. {
  537. //
  538. // Set the size of the local send bitmap cache to the minimum of its
  539. // current size and this party's receive bitmap cache size.
  540. //
  541. newSmallCellSize = min(newSmallCellSize,
  542. pasT->cpcCaps.bitmaps.receiver.capsSmallCacheCellSize);
  543. newSmallMaxEntries = min(newSmallMaxEntries,
  544. pasT->cpcCaps.bitmaps.receiver.capsSmallCacheNumEntries);
  545. newMediumCellSize = min(newMediumCellSize,
  546. pasT->cpcCaps.bitmaps.receiver.capsMediumCacheCellSize);
  547. newMediumMaxEntries = min(newMediumMaxEntries,
  548. pasT->cpcCaps.bitmaps.receiver.capsMediumCacheNumEntries);
  549. newLargeCellSize = min(newLargeCellSize,
  550. pasT->cpcCaps.bitmaps.receiver.capsLargeCacheCellSize);
  551. newLargeMaxEntries = min(newLargeMaxEntries,
  552. pasT->cpcCaps.bitmaps.receiver.capsLargeCacheNumEntries);
  553. }
  554. }
  555. TRACE_OUT(("Recalced SBC caps: Small {%d of %d}, Medium {%d of %d}, Large {%d of %d}",
  556. newSmallMaxEntries, newSmallCellSize,
  557. newMediumMaxEntries, newMediumCellSize,
  558. newLargeMaxEntries, newLargeCellSize));
  559. //
  560. // If we've changed the size, reset the cache before continuing.
  561. //
  562. if ((pSmall->cCellSize != newSmallCellSize) ||
  563. (pSmall->cEntries != newSmallMaxEntries))
  564. {
  565. m_pHost->SBC_RecreateSendCache(ID_SMALL_BMP_CACHE,
  566. newSmallMaxEntries,
  567. newSmallCellSize);
  568. cacheChanged = TRUE;
  569. }
  570. if ((pMedium->cCellSize != newMediumCellSize) ||
  571. (pMedium->cEntries != newMediumMaxEntries))
  572. {
  573. m_pHost->SBC_RecreateSendCache(ID_MEDIUM_BMP_CACHE,
  574. newMediumMaxEntries,
  575. newMediumCellSize);
  576. cacheChanged = TRUE;
  577. }
  578. if ((pLarge->cCellSize != newLargeCellSize) ||
  579. (pLarge->cEntries != newLargeMaxEntries))
  580. {
  581. m_pHost->SBC_RecreateSendCache(ID_LARGE_BMP_CACHE,
  582. newLargeMaxEntries,
  583. newLargeCellSize);
  584. cacheChanged = TRUE;
  585. }
  586. //
  587. // If we had to recreate any of the send caches, make sure that we
  588. // clear the fast path.
  589. //
  590. if (cacheChanged)
  591. {
  592. m_pHost->SBC_CacheCleared();
  593. }
  594. //
  595. // Handle new capabilities
  596. //
  597. //
  598. // Set up the new capabilities structure...
  599. //
  600. newCapabilities.sendingBpp = m_pHost->m_usrSendingBPP;
  601. newCapabilities.cacheInfo = m_pHost->m_asbcCacheInfo;
  602. //
  603. // ... and pass it through to the driver.
  604. //
  605. if (! OSI_FunctionRequest(SBC_ESC_NEW_CAPABILITIES,
  606. (LPOSI_ESCAPE_HEADER)&newCapabilities,
  607. sizeof(newCapabilities)))
  608. {
  609. ERROR_OUT(("SBC_ESC_NEW_CAPABILITIES failed"));
  610. }
  611. DC_EXIT_POINT:
  612. DebugExitVOID(ASShare::SBC_RecalcCaps);
  613. }
  614. //
  615. // FUNCTION: SBCCacheCallback
  616. //
  617. // DESCRIPTION:
  618. //
  619. // Send BMC Cache Manager callback function. Called whenever an entry is
  620. // removed from the cache to allow us to free up the object.
  621. //
  622. // PARAMETERS:
  623. //
  624. // hCache - cache handle
  625. //
  626. // event - the cache event that has occured
  627. //
  628. // iCacheEntry - index of the cache entry that the event is affecting
  629. //
  630. // pData - pointer to the cache data associated with the given cache entry
  631. //
  632. // cbDataSize - size in bytes of the cached data
  633. //
  634. // RETURNS: Nothing
  635. //
  636. //
  637. void SBCCacheCallback
  638. (
  639. ASHost * pHost,
  640. PCHCACHE pCache,
  641. UINT iCacheEntry,
  642. LPBYTE pData
  643. )
  644. {
  645. UINT cache;
  646. DebugEntry(SBCCacheCallback);
  647. //
  648. // Simply release the cache entry for reuse. We must scan for
  649. // the correct cache root
  650. //
  651. for (cache = 0; cache < NUM_BMP_CACHES; cache++)
  652. {
  653. if (pHost->m_asbcBmpCaches[cache].handle == pCache)
  654. {
  655. pHost->m_asbcBmpCaches[cache].freeEntry = (PBMC_DIB_ENTRY)pData;
  656. pHost->m_asbcBmpCaches[cache].freeEntry->inUse = FALSE;
  657. TRACE_OUT(("0x%08x SBC cache entry 0x%08x now free", pCache, pData));
  658. pHost->SBC_CacheEntryRemoved(cache, iCacheEntry);
  659. break;
  660. }
  661. }
  662. DebugExitVOID(SBCCacheCallback);
  663. }
  664. //
  665. //
  666. // SBC_ProcessMemBltOrder()
  667. //
  668. //
  669. BOOL ASHost::SBC_ProcessMemBltOrder
  670. (
  671. LPINT_ORDER pOrder,
  672. LPINT_ORDER * ppNextOrder
  673. )
  674. {
  675. BOOL rc = FALSE;
  676. UINT orderType;
  677. UINT tileId;
  678. UINT tileType;
  679. LPSBC_TILE_DATA pTileData = NULL;
  680. UINT bitmapWidth;
  681. int bitmapHeight;
  682. LPINT_ORDER pBMCOrder = NULL;
  683. UINT colorCacheIndex;
  684. UINT bitsCache;
  685. UINT bitsCacheIndex;
  686. UINT numColors;
  687. LPLONG pXSrc;
  688. LPLONG pYSrc;
  689. BOOL isNewColorTableEntry;
  690. BOOL isNewBitsEntry;
  691. BOOL canFastPath = TRUE;
  692. LPMEMBLT_ORDER pMemBltOrder = (LPMEMBLT_ORDER)&(pOrder->abOrderData);
  693. LPMEM3BLT_ORDER pMem3BltOrder = (LPMEM3BLT_ORDER)pMemBltOrder;
  694. LPMEMBLT_R2_ORDER pMemBltR2Order = (LPMEMBLT_R2_ORDER)pMemBltOrder;
  695. LPMEM3BLT_R2_ORDER pMem3BltR2Order = (LPMEM3BLT_R2_ORDER)pMemBltOrder;
  696. BITMAPINFO_ours sbcBitmapInfo;
  697. DebugEntry(ASHost::SBC_ProcessMemBltOrder);
  698. *ppNextOrder = NULL;
  699. //
  700. // We may already have processed this MEMBLT order and have the color
  701. // table and bitmap bits for it, ready to go across the wire. This
  702. // would happen if the update packager called this function to process
  703. // the MEMBLT, but then didn't have enough room in its current network
  704. // packet to send the color table or the bitmap bits.
  705. //
  706. // So, if we've already processed this order, bail out now.
  707. //
  708. if (m_sbcOrderInfo.pOrder == pOrder)
  709. {
  710. //
  711. // We've got a match ! Do we have valid data for it ? If we don't
  712. // we must have failed last time, so we'll probably fail again (we
  713. // don't do any memory allocation, so it's unlikely that the error
  714. // condition has cleared up). In any case, we should not have been
  715. // called again if we failed last time...
  716. //
  717. if (m_sbcOrderInfo.validData)
  718. {
  719. TRACE_OUT(( "Already have valid data for this MEMBLT"));
  720. rc = TRUE;
  721. }
  722. else
  723. {
  724. WARNING_OUT(( "Have invalid data for this MEMBLT"));
  725. }
  726. DC_QUIT;
  727. }
  728. //
  729. // Re-initialise m_sbcOrderInfo
  730. //
  731. m_sbcOrderInfo.pOrder = pOrder;
  732. m_sbcOrderInfo.validData = FALSE;
  733. m_sbcOrderInfo.sentColorTable = FALSE;
  734. m_sbcOrderInfo.sentBitmapBits = FALSE;
  735. m_sbcOrderInfo.sentMemBlt = FALSE;
  736. //
  737. // Here's on overview of what we do here...
  738. //
  739. // We've been given a MEMBLT order which references an entry in a shunt
  740. // buffer containing the bits for the MEMBLT at the native bpp (the bpp
  741. // of the display). We want to cache the bits and a color table at the
  742. // protocol bpp. So, we
  743. //
  744. // - copy the bits from the shunt buffer into a work DIB section
  745. // - call GetDIBits to get the data from the work DIB section at the
  746. // protocol bpp
  747. // - cache the bits and the color table
  748. // - if we add new cache entries for the bits and / or the color table,
  749. // we fill in m_sbcOrderInfo.pBitmapBits order and / or
  750. // m_sbcOrderInfo.pColorTableInfo to hold the orders to be sent before
  751. // the MEMBLT order.
  752. //
  753. //
  754. // Make sure that we've been given the correct order type. Note that
  755. // we will never be given the R2 versions of the MEMBLT orders.
  756. //
  757. orderType = pMemBltOrder->type;
  758. ASSERT(((orderType == ORD_MEMBLT_TYPE) ||
  759. (orderType == ORD_MEM3BLT_TYPE)));
  760. //
  761. // Get a pointer to the entry in one of the shunt buffers which matches
  762. // this order.
  763. //
  764. if (orderType == ORD_MEMBLT_TYPE)
  765. {
  766. tileId = pMemBltOrder->cacheId;
  767. }
  768. else
  769. {
  770. tileId = pMem3BltOrder->cacheId;
  771. }
  772. if (!SBCGetTileData(tileId, &pTileData, &tileType))
  773. {
  774. ERROR_OUT(( "Failed to find entry for tile %hx in shunt buffer",
  775. tileId));
  776. DC_QUIT;
  777. }
  778. bitmapWidth = pTileData->width;
  779. bitmapHeight = pTileData->height;
  780. //
  781. // Check if we should do any fast path operations on this bitmap
  782. //
  783. if (pTileData->majorCacheInfo == SBC_DONT_FASTPATH)
  784. {
  785. TRACE_OUT(( "Tile %x should not be fastpathed", tileId));
  786. canFastPath = FALSE;
  787. }
  788. //
  789. // Try to find an entry for this bitmap in the fast path (unless the
  790. // bitmap is marked as being non-fastpathable).
  791. //
  792. if (canFastPath && SBCFindInFastPath(pTileData->majorCacheInfo,
  793. pTileData->minorCacheInfo,
  794. pTileData->majorPalette,
  795. pTileData->minorPalette,
  796. pTileData->srcX,
  797. pTileData->srcY,
  798. pTileData->tilingWidth,
  799. pTileData->tilingHeight,
  800. &bitsCache,
  801. &bitsCacheIndex,
  802. &colorCacheIndex))
  803. {
  804. isNewBitsEntry = FALSE;
  805. isNewColorTableEntry = FALSE;
  806. //
  807. // Call the cache handler to get it to update its MRU entry for
  808. // this cache entry
  809. //
  810. CH_TouchCacheEntry(m_asbcBmpCaches[bitsCache].handle, bitsCacheIndex);
  811. }
  812. else
  813. {
  814. //
  815. // There is no entry in the fast path...
  816. //
  817. // Copy the data from the tile in the shunt buffer into the work
  818. // DIB section. Note that this only works correctly because both
  819. // our work DIB and the tile data are "top down" rather than the
  820. // default of "bottom up". i.e the data for the first scanline is
  821. // stored first in memory. If this wasn't the case, we'd have to
  822. // work out an offset into the work DIB to start copying to.
  823. //
  824. memcpy(m_asbcWorkInfo[tileType].pWorkBitmapBits,
  825. pTileData->bitData,
  826. pTileData->bytesUsed);
  827. //
  828. // Now set up the destination for the GetDIBits call. First set up
  829. // a bitmap info header to pass to GetDIBits. Only the header part
  830. // of the structure will be sent across the network - the color
  831. // table is sent via the palette packets.
  832. //
  833. // Note that we set the height in the bitmap info header to be
  834. // negative. This forces a convertion from our "top down" DIB
  835. // format to the default "bottom up" format which we want to cache
  836. // and send over the wire.
  837. //
  838. ZeroMemory(&sbcBitmapInfo, sizeof(sbcBitmapInfo));
  839. m_pShare->USR_InitDIBitmapHeader((BITMAPINFOHEADER *)&sbcBitmapInfo,
  840. m_usrSendingBPP);
  841. sbcBitmapInfo.bmiHeader.biWidth = m_asbcWorkInfo[tileType].tileWidth;
  842. sbcBitmapInfo.bmiHeader.biHeight = -(int)m_asbcWorkInfo[tileType].tileHeight;
  843. //
  844. // OK, we've set up the source and the destination, so now get the
  845. // data at the protocol bpp. We get the bits into the usr general
  846. // bitmap work buffer.
  847. //
  848. if (GetDIBits(m_usrWorkDC,
  849. m_asbcWorkInfo[tileType].workBitmap,
  850. 0,
  851. bitmapHeight,
  852. m_pShare->m_usrPBitmapBuffer,
  853. (BITMAPINFO *)&sbcBitmapInfo,
  854. DIB_RGB_COLORS) != (int)bitmapHeight)
  855. {
  856. ERROR_OUT(( "GetDIBits failed"));
  857. DC_QUIT;
  858. }
  859. TRACE_OUT(( "%d x %d, (fixed %d) -> (%d, %d)",
  860. bitmapWidth,
  861. bitmapHeight,
  862. m_asbcWorkInfo[tileType].tileWidth,
  863. pMemBltOrder->nLeftRect,
  864. pMemBltOrder->nTopRect));
  865. numColors = COLORS_FOR_BPP(m_usrSendingBPP);
  866. //
  867. // There is no color table to cache if there is no color table at
  868. // all, which is the case when sending at 24BPP
  869. //
  870. if (numColors)
  871. {
  872. //
  873. // Cache the color table. If this succeeds, colorCacheIndex will
  874. // be set up to contain the details of the cache entry which the
  875. // data is cached in. In addition, if isNewColorTableEntry is TRUE
  876. // on return, psbcOrders.colorTableOrder will be fully initialized
  877. // and ready to go across the wire.
  878. //
  879. if (!SBCCacheColorTable(m_sbcOrderInfo.pColorTableOrder,
  880. sbcBitmapInfo.bmiColors,
  881. numColors,
  882. &colorCacheIndex,
  883. &isNewColorTableEntry))
  884. {
  885. TRACE_OUT(( "Failed to cache color table"));
  886. DC_QUIT;
  887. }
  888. ASSERT(colorCacheIndex != COLORCACHEINDEX_NONE);
  889. }
  890. else
  891. {
  892. colorCacheIndex = COLORCACHEINDEX_NONE;
  893. isNewColorTableEntry = FALSE;
  894. }
  895. //
  896. // Cache the bits. If this succeeds, bitsCache and bitsCacheIndex
  897. // will be set up to contain the details of the cache entry which
  898. // the data is cached in. In addition, if isNewBitsEntry is TRUE
  899. // on return, psbcOrders.bitmapBitsOrder will be fully initialized
  900. // and ready to go across the wire.
  901. //
  902. // If this fails, the above values will be undefined.
  903. //
  904. if (!SBCCacheBits(m_sbcOrderInfo.pBitmapBitsOrder,
  905. m_sbcOrderInfo.bitmapBitsDataSize,
  906. m_pShare->m_usrPBitmapBuffer,
  907. bitmapWidth,
  908. m_asbcWorkInfo[tileType].tileWidth,
  909. bitmapHeight,
  910. BYTES_IN_BITMAP(m_asbcWorkInfo[tileType].tileWidth,
  911. bitmapHeight,
  912. sbcBitmapInfo.bmiHeader.biBitCount),
  913. &bitsCache,
  914. &bitsCacheIndex,
  915. &isNewBitsEntry))
  916. {
  917. TRACE_OUT(( "Failed to cache bits"));
  918. DC_QUIT;
  919. }
  920. //
  921. // Add the newly cached item to the fast path (unless the bitmap is
  922. // marked as being non-fastpathable).
  923. //
  924. if (canFastPath)
  925. {
  926. SBCAddToFastPath(pTileData->majorCacheInfo,
  927. pTileData->minorCacheInfo,
  928. pTileData->majorPalette,
  929. pTileData->minorPalette,
  930. pTileData->srcX,
  931. pTileData->srcY,
  932. pTileData->tilingWidth,
  933. pTileData->tilingHeight,
  934. bitsCache,
  935. bitsCacheIndex,
  936. colorCacheIndex);
  937. }
  938. }
  939. //
  940. // We've now got valid cache entries for the DIB bits and the color
  941. // table, so we should now fill them into the MEMBLT order.
  942. //
  943. // Set up the source co-ordinates. For R1 protocols, the x-coordinate
  944. // includes the offset which is required to get the right cell within
  945. // the receive bitmap cache. For R2, we set up the cache entry in a
  946. // separate field.
  947. //
  948. if (orderType == ORD_MEMBLT_TYPE)
  949. {
  950. pXSrc = &pMemBltOrder->nXSrc;
  951. pYSrc = &pMemBltOrder->nYSrc;
  952. }
  953. else
  954. {
  955. pXSrc = &pMem3BltOrder->nXSrc;
  956. pYSrc = &pMem3BltOrder->nYSrc;
  957. }
  958. *pXSrc = *pXSrc % pTileData->tilingWidth;
  959. *pYSrc = *pYSrc % pTileData->tilingHeight;
  960. //
  961. // The sub-bitmap and color table are in the cache. Store a cache
  962. // handle and color handle. Also store the cache index for R2
  963. // protocols (see above).
  964. //
  965. if (orderType == ORD_MEMBLT_TYPE)
  966. {
  967. pMemBltOrder->cacheId = MEMBLT_COMBINEHANDLES(colorCacheIndex,
  968. bitsCache);
  969. pMemBltR2Order->type = (TSHR_UINT16)ORD_MEMBLT_R2_TYPE;
  970. pMemBltR2Order->cacheIndex = (TSHR_UINT16)bitsCacheIndex;
  971. TRACE_OUT(( "MEMBLT color %u bitmap %u:%u",
  972. colorCacheIndex,
  973. bitsCache,
  974. bitsCacheIndex));
  975. }
  976. else
  977. {
  978. pMem3BltOrder->cacheId = MEMBLT_COMBINEHANDLES(colorCacheIndex,
  979. bitsCache);
  980. pMem3BltR2Order->type = ORD_MEM3BLT_R2_TYPE;
  981. pMem3BltR2Order->cacheIndex = (TSHR_UINT16)bitsCacheIndex;
  982. TRACE_OUT(( "MEM3BLT color %u bitmap %u:%u",
  983. colorCacheIndex,
  984. bitsCache,
  985. bitsCacheIndex));
  986. }
  987. //
  988. // Must have successfully completed processing the order to get to
  989. // here. Fill in the appropriate info in the m_sbcOrderInfo structure.
  990. // If we got a cache hit on the color table or the bitmap bits then
  991. // we've already sent the data for them.
  992. //
  993. m_sbcOrderInfo.validData = TRUE;
  994. m_sbcOrderInfo.sentColorTable = !isNewColorTableEntry;
  995. m_sbcOrderInfo.sentBitmapBits = !isNewBitsEntry;
  996. rc = TRUE;
  997. DC_EXIT_POINT:
  998. if (rc)
  999. {
  1000. //
  1001. // We've successfully processed the MEMBLT, so set up a pointer to
  1002. // the next order which should be sent by the caller.
  1003. //
  1004. // Note that if we have already sent these orders, then we return
  1005. // a NULL order.
  1006. //
  1007. if (!m_sbcOrderInfo.sentColorTable)
  1008. {
  1009. TRACE_OUT(( "Returning color table order"));
  1010. *ppNextOrder = m_sbcOrderInfo.pColorTableOrder;
  1011. }
  1012. else if (!m_sbcOrderInfo.sentBitmapBits)
  1013. {
  1014. TRACE_OUT(( "Returning bitmap bits order"));
  1015. *ppNextOrder = m_sbcOrderInfo.pBitmapBitsOrder;
  1016. }
  1017. else if (!m_sbcOrderInfo.sentMemBlt)
  1018. {
  1019. TRACE_OUT(( "Returning MemBlt order"));
  1020. *ppNextOrder = pOrder;
  1021. }
  1022. else
  1023. {
  1024. TRACE_OUT(( "No order to return"));
  1025. rc = FALSE;
  1026. }
  1027. }
  1028. //
  1029. // We've finished with the entry in the shunt buffer, so reset the
  1030. // inUse flag to allow the driver to re-use it.
  1031. //
  1032. if (pTileData != NULL)
  1033. {
  1034. pTileData->inUse = FALSE;
  1035. }
  1036. DebugExitBOOL(ASHost::SBC_ProcessMemBltOrder, rc);
  1037. return(rc);
  1038. }
  1039. //
  1040. //
  1041. // SBC_OrderSentNotification()
  1042. //
  1043. //
  1044. void ASHost::SBC_OrderSentNotification(LPINT_ORDER pOrder)
  1045. {
  1046. DebugEntry(ASHost::SBC_OrderSentNotification);
  1047. //
  1048. // pOrder should be a pointer to either our internal bitmap bits order,
  1049. // or our color table order.
  1050. //
  1051. if (pOrder == m_sbcOrderInfo.pBitmapBitsOrder)
  1052. {
  1053. TRACE_OUT(( "Bitmap bits order has been sent"));
  1054. m_sbcOrderInfo.sentBitmapBits = TRUE;
  1055. }
  1056. else if (pOrder == m_sbcOrderInfo.pColorTableOrder)
  1057. {
  1058. TRACE_OUT(( "Color table order has been sent"));
  1059. m_sbcOrderInfo.sentColorTable = TRUE;
  1060. }
  1061. else if (pOrder == m_sbcOrderInfo.pOrder)
  1062. {
  1063. TRACE_OUT(( "Memblt order has been sent"));
  1064. m_sbcOrderInfo.sentMemBlt = TRUE;
  1065. //
  1066. // All parts of the Memblt have been sent now, so reset our pointer
  1067. // to the order. This avoids a problem where
  1068. // SBC_ProcessMemBltOrder is called twice in a row with the same
  1069. // pOrder, but with different data (i.e. consecutive MemBlts
  1070. // ending up in the same point in the order heap). It can happen...
  1071. //
  1072. m_sbcOrderInfo.pOrder = NULL;
  1073. }
  1074. else
  1075. {
  1076. ERROR_OUT(( "Notification for unknown order %#.8lx", pOrder));
  1077. }
  1078. DebugExitVOID(ASHost::SBC_OrderSentNotification);
  1079. }
  1080. //
  1081. //
  1082. // SBC_ProcessInternalOrder()
  1083. //
  1084. //
  1085. void ASHost::SBC_ProcessInternalOrder(LPINT_ORDER pOrder)
  1086. {
  1087. UINT orderType;
  1088. LPINT_COLORTABLE_ORDER_1BPP pColorTableOrder;
  1089. HBITMAP oldBitmap = 0;
  1090. UINT numEntries;
  1091. int i;
  1092. DebugEntry(ASHost::SBC_ProcessInternalOrder);
  1093. //
  1094. // Make sure that we've been given an order type which we recognise.
  1095. // Currently, the only internal order we support is a color table
  1096. // order.
  1097. //
  1098. pColorTableOrder = (LPINT_COLORTABLE_ORDER_1BPP)&(pOrder->abOrderData);
  1099. orderType = pColorTableOrder->header.type;
  1100. ASSERT(orderType == INTORD_COLORTABLE_TYPE);
  1101. //
  1102. // Make sure that the color table order is the same bpp as the work DIB
  1103. // sections.
  1104. //
  1105. ASSERT(pColorTableOrder->header.bpp == g_usrCaptureBPP);
  1106. //
  1107. // All we have to do is to copy the color table from the order into our
  1108. // two work DIB sections. To do that, we have to select the DIB
  1109. // sections into a DC then set the color table for the DC - this sets
  1110. // the color table in the DIB section.
  1111. //
  1112. numEntries = COLORS_FOR_BPP(g_usrCaptureBPP);
  1113. ASSERT(numEntries);
  1114. for (i = 0 ; i < SBC_NUM_TILE_SIZES; i++)
  1115. {
  1116. oldBitmap = SelectBitmap(m_usrWorkDC, m_asbcWorkInfo[i].workBitmap);
  1117. SetDIBColorTable(m_usrWorkDC,
  1118. 0, // First index
  1119. numEntries, // Number of entries
  1120. (RGBQUAD*)pColorTableOrder->colorData);
  1121. }
  1122. if (oldBitmap != NULL)
  1123. {
  1124. SelectBitmap(m_usrWorkDC, oldBitmap);
  1125. }
  1126. DebugExitVOID(ASHost::SBC_ProcessInternalOrder);
  1127. }
  1128. //
  1129. //
  1130. // SBC_PMCacheEntryRemoved()
  1131. //
  1132. //
  1133. void ASHost::SBC_PMCacheEntryRemoved(UINT cacheIndex)
  1134. {
  1135. LPSBC_FASTPATH_ENTRY pEntry;
  1136. LPSBC_FASTPATH_ENTRY pNextEntry;
  1137. DebugEntry(ASHost::SBC_PMCacheEntryRemoved);
  1138. ASSERT(m_sbcFastPath);
  1139. //
  1140. // An entry has been removed from the color cache. We have to remove
  1141. // all entries from the fast path which reference this color table.
  1142. //
  1143. TRACE_OUT(( "Color table cache entry %d removed - removing references",
  1144. cacheIndex));
  1145. pEntry = (LPSBC_FASTPATH_ENTRY)COM_BasedListFirst(&m_sbcFastPath->usedList, FIELD_OFFSET(SBC_FASTPATH_ENTRY, list));
  1146. while (pEntry != NULL)
  1147. {
  1148. pNextEntry = (LPSBC_FASTPATH_ENTRY)COM_BasedListNext(&m_sbcFastPath->usedList, pEntry,
  1149. FIELD_OFFSET(SBC_FASTPATH_ENTRY, list));
  1150. if (pEntry->colorIndex == cacheIndex)
  1151. {
  1152. COM_BasedListRemove(&pEntry->list);
  1153. COM_BasedListInsertAfter(&m_sbcFastPath->freeList, &pEntry->list);
  1154. }
  1155. pEntry = pNextEntry;
  1156. }
  1157. DebugExitVOID(ASHost::SBC_PMCacheEntryRemoved);
  1158. }
  1159. //
  1160. //
  1161. // Name: SBCInitInternalOrders
  1162. //
  1163. // Purpose: Allocate memory for the internal orders used during MEMBLT
  1164. // order processing.
  1165. //
  1166. // Returns: TRUE if initialized OK, FALSE otherwise.
  1167. //
  1168. // Params: None
  1169. //
  1170. // Operation: If successful, this function initializes the following
  1171. //
  1172. // g_Share->sbcOrderInfo
  1173. //
  1174. //
  1175. BOOL ASHost::SBCInitInternalOrders(void)
  1176. {
  1177. BOOL initOK = FALSE;
  1178. UINT orderSize;
  1179. LPINT_ORDER_HEADER pOrderHeader;
  1180. DebugEntry(ASHost::SBCInitInternalOrders);
  1181. //
  1182. // Start with the bitmap bits order. Calculate the number of bytes
  1183. // required to store the bits for the largest bitmap bits order we will
  1184. // ever send. This includes room for the compression header which gets
  1185. // added before the bits if the data is compressed.
  1186. //
  1187. if (g_usrCaptureBPP >= 24)
  1188. {
  1189. // Can possibly send 24bpp TRUE COLOR data
  1190. m_sbcOrderInfo.bitmapBitsDataSize =
  1191. BYTES_IN_BITMAP(MP_LARGE_TILE_WIDTH, MP_LARGE_TILE_HEIGHT, 24)
  1192. + sizeof(CD_HEADER);
  1193. }
  1194. else
  1195. {
  1196. // Can't send 24bpp TRUE color data
  1197. m_sbcOrderInfo.bitmapBitsDataSize =
  1198. BYTES_IN_BITMAP(MP_LARGE_TILE_WIDTH, MP_LARGE_TILE_WIDTH, 8)
  1199. + sizeof(CD_HEADER);
  1200. }
  1201. //
  1202. // Now allocate memory for the bitmap bits order. The size required
  1203. // is:
  1204. // The size of an INT_ORDER_HEADER (this is added in by OA when you
  1205. // call OA_AllocOrderMem)
  1206. // + the size of the largest BMC_BITMAP_BITS_ORDER structure
  1207. // + the number of bytes required for the bitmap bits
  1208. // + contingency for RLE compression overruns !
  1209. //
  1210. orderSize = sizeof(INT_ORDER_HEADER)
  1211. + sizeof(BMC_BITMAP_BITS_ORDER_R2)
  1212. + m_sbcOrderInfo.bitmapBitsDataSize
  1213. + 4;
  1214. TRACE_OUT(( "Allocating %d bytes for SBC bitmap bits order (bits %d)",
  1215. orderSize,
  1216. m_sbcOrderInfo.bitmapBitsDataSize));
  1217. m_sbcOrderInfo.pBitmapBitsOrder = (LPINT_ORDER)new BYTE[orderSize];
  1218. if (!m_sbcOrderInfo.pBitmapBitsOrder)
  1219. {
  1220. ERROR_OUT((
  1221. "Failed to alloc %d bytes for SBC bitmap bits order (bits %d)",
  1222. orderSize,
  1223. m_sbcOrderInfo.bitmapBitsDataSize));
  1224. DC_QUIT;
  1225. }
  1226. //
  1227. // Initialize the INT_ORDER_HEADER - this is normally done in
  1228. // OA_AllocOrderMem(). For the bitmap bits order, we can't fill in the
  1229. // orderLength because it is not a fixed size - this has to be done
  1230. // later when we fill in the bitmap bits. Note that the order length
  1231. // excludes the size of the INT_ORDER_HEADER.
  1232. //
  1233. pOrderHeader = &m_sbcOrderInfo.pBitmapBitsOrder->OrderHeader;
  1234. pOrderHeader->additionalOrderData = 0;
  1235. pOrderHeader->cbAdditionalOrderDataLength = 0;
  1236. //
  1237. // Now the color table order. The size required is:
  1238. // The size of an INT_ORDER_HEADER (this is added in by OA when you
  1239. // call OA_AllocOrderMem)
  1240. // + the size of a BMC_COLOR_TABLE_ORDER structure
  1241. // + the number of bytes required for the color table entries (note
  1242. // that the BMC_COLOR_TABLE_ORDER structure contains the first
  1243. // color table entry, so adjust the number of extra bytes required)
  1244. //
  1245. // Color tables are only for 8bpp and less.
  1246. orderSize = sizeof(INT_ORDER_HEADER)
  1247. + sizeof(BMC_COLOR_TABLE_ORDER)
  1248. + (COLORS_FOR_BPP(8) - 1) * sizeof(TSHR_RGBQUAD);
  1249. TRACE_OUT(( "Allocating %d bytes for SBC color table order", orderSize));
  1250. m_sbcOrderInfo.pColorTableOrder = (LPINT_ORDER)new BYTE[orderSize];
  1251. if (!m_sbcOrderInfo.pColorTableOrder)
  1252. {
  1253. ERROR_OUT(( "Failed to alloc %d bytes for SBC color table order",
  1254. orderSize));
  1255. DC_QUIT;
  1256. }
  1257. pOrderHeader = &m_sbcOrderInfo.pColorTableOrder->OrderHeader;
  1258. pOrderHeader->additionalOrderData = 0;
  1259. pOrderHeader->cbAdditionalOrderDataLength = 0;
  1260. pOrderHeader->Common.cbOrderDataLength = (WORD)(orderSize - sizeof(INT_ORDER_HEADER));
  1261. //
  1262. // Fill in the remaining fields in m_sbcOrderInfo
  1263. //
  1264. m_sbcOrderInfo.pOrder = NULL;
  1265. m_sbcOrderInfo.validData = FALSE;
  1266. m_sbcOrderInfo.sentColorTable = FALSE;
  1267. m_sbcOrderInfo.sentBitmapBits = FALSE;
  1268. m_sbcOrderInfo.sentMemBlt = FALSE;
  1269. //
  1270. // Must be OK to get to here
  1271. //
  1272. initOK = TRUE;
  1273. DC_EXIT_POINT:
  1274. DebugExitDWORD(ASHost::SBCInitInternalOrders, initOK);
  1275. return(initOK);
  1276. }
  1277. //
  1278. //
  1279. // Name: SBCFreeInternalOrders
  1280. //
  1281. // Purpose: Free up the internal orders used by SBC during MEMBLT order
  1282. // processing.
  1283. //
  1284. // Returns: Nothing
  1285. //
  1286. // Params: None
  1287. //
  1288. //
  1289. void ASHost::SBCFreeInternalOrders(void)
  1290. {
  1291. DebugEntry(ASHost::SBCFreeInternalOrders);
  1292. //
  1293. // First free up the memory.
  1294. //
  1295. if (m_sbcOrderInfo.pBitmapBitsOrder)
  1296. {
  1297. delete m_sbcOrderInfo.pBitmapBitsOrder;
  1298. m_sbcOrderInfo.pBitmapBitsOrder = NULL;
  1299. }
  1300. if (m_sbcOrderInfo.pColorTableOrder)
  1301. {
  1302. delete m_sbcOrderInfo.pColorTableOrder;
  1303. m_sbcOrderInfo.pColorTableOrder = NULL;
  1304. }
  1305. //
  1306. // Now reset the remaining fields in m_sbcOrderInfo
  1307. //
  1308. m_sbcOrderInfo.pOrder = NULL;
  1309. m_sbcOrderInfo.validData = FALSE;
  1310. m_sbcOrderInfo.sentColorTable = FALSE;
  1311. m_sbcOrderInfo.sentBitmapBits = FALSE;
  1312. m_sbcOrderInfo.bitmapBitsDataSize = 0;
  1313. DebugExitVOID(ASHost::SBCFreeInternalOrders);
  1314. }
  1315. //
  1316. //
  1317. // Name: SBCInitFastPath
  1318. //
  1319. // Purpose: Initialize the SBC fast path
  1320. //
  1321. // Returns: TRUE if successful, FALSE otherwise
  1322. //
  1323. // Params: None
  1324. //
  1325. //
  1326. BOOL ASHost::SBCInitFastPath(void)
  1327. {
  1328. BOOL rc = FALSE;
  1329. DebugEntry(ASHost::SBCInitFastPath);
  1330. m_sbcFastPath = new SBC_FASTPATH;
  1331. if (!m_sbcFastPath)
  1332. {
  1333. ERROR_OUT(("Failed to alloc m_sbcFastPath"));
  1334. DC_QUIT;
  1335. }
  1336. SET_STAMP(m_sbcFastPath, SBCFASTPATH);
  1337. //
  1338. // Initialize the structure.
  1339. //
  1340. SBC_CacheCleared();
  1341. rc = TRUE;
  1342. DC_EXIT_POINT:
  1343. DebugExitBOOL(ASHost::SBCInitFastPath, rc);
  1344. return(rc);
  1345. }
  1346. //
  1347. //
  1348. // Name: SBCGetTileData
  1349. //
  1350. // Purpose: Given the ID of a tile data entry in one of the SBC shunt
  1351. // buffers, return a pointer to the entry with that ID.
  1352. //
  1353. // Returns: TRUE if the entry is found, FALSE otherwise
  1354. //
  1355. // Params: IN tileId - The ID of the shunt buffer entry to be
  1356. // found.
  1357. // OUT ppTileData - A pointer to the start of the shunt buffer
  1358. // entry (if found)
  1359. // OUT pTileType - The type of shunt buffer entry found. One
  1360. // of:
  1361. // SBC_MEDIUM_TILE
  1362. // SBC_LARGE_TILE
  1363. //
  1364. //
  1365. BOOL ASHost::SBCGetTileData
  1366. (
  1367. UINT tileId,
  1368. LPSBC_TILE_DATA * ppTileData,
  1369. LPUINT pTileType
  1370. )
  1371. {
  1372. BOOL gotTileData = FALSE;
  1373. UINT workTile;
  1374. LPSBC_TILE_DATA pWorkTile;
  1375. DebugEntry(ASHost::SBCGetTileData);
  1376. TRACE_OUT(( "Looking for tile Id %x", tileId));
  1377. //
  1378. // Find out which of the shunt buffers the entry should be in.
  1379. //
  1380. *pTileType = SBC_TILE_TYPE(tileId);
  1381. //
  1382. // We implement the shunt buffers as circular FIFO queues, so in
  1383. // general, we are looking for the entry following the last one which
  1384. // we found. However, this wont always be the case because we do some
  1385. // out of order processing when we do spoiling.
  1386. //
  1387. // So, get the index of the last tile we accessed.
  1388. //
  1389. workTile = m_asbcWorkInfo[*pTileType].mruIndex;
  1390. //
  1391. // OK, so lets go for it ! Start at the tile following the last one we
  1392. // accessed, and loop through the circular buffer until we get a match,
  1393. // or have circled back to the beginning.
  1394. //
  1395. // Note that this has been coded as a "do while" loop, rather than just
  1396. // a "while" loop so that we don't miss mruTile.
  1397. //
  1398. do
  1399. {
  1400. //
  1401. // On to the next tile
  1402. //
  1403. workTile++;
  1404. if (workTile == m_asbcWorkInfo[*pTileType].pShuntBuffer->numEntries)
  1405. {
  1406. workTile = 0;
  1407. }
  1408. pWorkTile = SBCTilePtrFromIndex(m_asbcWorkInfo[*pTileType].pShuntBuffer,
  1409. workTile);
  1410. if (pWorkTile->inUse)
  1411. {
  1412. if (pWorkTile->tileId == tileId)
  1413. {
  1414. //
  1415. // We've got a match.
  1416. //
  1417. TRACE_OUT(( "Matched tile Id %x at index %d",
  1418. tileId,
  1419. workTile));
  1420. *ppTileData = pWorkTile;
  1421. gotTileData = TRUE;
  1422. m_asbcWorkInfo[*pTileType].mruIndex = workTile;
  1423. DC_QUIT;
  1424. }
  1425. }
  1426. }
  1427. while (workTile != m_asbcWorkInfo[*pTileType].mruIndex);
  1428. //
  1429. // If we get to here, we've not found a match.
  1430. //
  1431. TRACE_OUT(( "No match for tile Id %x", tileId));
  1432. DC_EXIT_POINT:
  1433. DebugExitBOOL(ASHost::SBCGetTileData, gotTileData);
  1434. return(gotTileData);
  1435. }
  1436. //
  1437. //
  1438. // Name: SBCCacheColorTable
  1439. //
  1440. // Purpose: Ensure that the given color table is cached.
  1441. //
  1442. // Returns: TRUE if the color table is cached successfully, FALSE
  1443. // otherwise.
  1444. //
  1445. // Params: IN pOrder - A pointer to a color table order to be
  1446. // filled in.
  1447. // IN pColorTable - A pointer to the start of the color table
  1448. // to be cached.
  1449. // IN numColors - The number of colors in the color table.
  1450. // OUT pCacheIndex - The index of the cached color table.
  1451. // OUT pIsNewEntry - TRUE if we added a new cache entry,
  1452. // FALSE if we matched an existing entry.
  1453. //
  1454. // Operation: pOrder is only filled in if *pIsNewEntry is FALSE.
  1455. //
  1456. //
  1457. BOOL ASHost::SBCCacheColorTable
  1458. (
  1459. LPINT_ORDER pOrder,
  1460. LPTSHR_RGBQUAD pColorTable,
  1461. UINT numColors,
  1462. UINT * pCacheIndex,
  1463. LPBOOL pIsNewEntry
  1464. )
  1465. {
  1466. BOOL cachedOK = FALSE;
  1467. UINT cacheIndex;
  1468. PBMC_COLOR_TABLE_ORDER pColorTableOrder;
  1469. DebugEntry(ASHost::SBCCacheColorTable);
  1470. //
  1471. // Call PM to do the caching.
  1472. //
  1473. if (!PM_CacheTxColorTable(&cacheIndex,
  1474. pIsNewEntry,
  1475. numColors,
  1476. pColorTable))
  1477. {
  1478. ERROR_OUT(( "Failed to cache color table"));
  1479. DC_QUIT;
  1480. }
  1481. //
  1482. // If the cache operation resulted in a cache update then we have to
  1483. // fill in the color table order.
  1484. //
  1485. if (*pIsNewEntry)
  1486. {
  1487. //
  1488. // The color table is new so we have to transmit it
  1489. //
  1490. TRACE_OUT(( "New color table"));
  1491. pOrder->OrderHeader.Common.fOrderFlags = OF_PRIVATE;
  1492. pColorTableOrder = (PBMC_COLOR_TABLE_ORDER)(pOrder->abOrderData);
  1493. pColorTableOrder->bmcPacketType = BMC_PT_COLOR_TABLE;
  1494. pColorTableOrder->colorTableSize = (TSHR_UINT16)numColors;
  1495. pColorTableOrder->index = (BYTE)cacheIndex;
  1496. //
  1497. // Copy the new color table into the Order Packet.
  1498. //
  1499. memcpy(pColorTableOrder->data, pColorTable,
  1500. numColors * sizeof(TSHR_RGBQUAD));
  1501. }
  1502. else
  1503. {
  1504. TRACE_OUT(( "Existing color table"));
  1505. }
  1506. //
  1507. // Return the color table index to the caller
  1508. //
  1509. *pCacheIndex = cacheIndex;
  1510. cachedOK = TRUE;
  1511. DC_EXIT_POINT:
  1512. DebugExitBOOL(ASHost::SBCCacheColorTable, cachedOK);
  1513. return(cachedOK);
  1514. }
  1515. //
  1516. //
  1517. // Name: SBCCacheBits
  1518. //
  1519. // Purpose: This function adds the supplied bitmap bits to a bitmap
  1520. // cache. The cache selected depends on the bitmap size, but
  1521. // may be different for R1 and R2. SBCSelectCache handles the
  1522. // determination of the correct cache.
  1523. //
  1524. // Returns: TRUE if the bits have been cached OK, FALSE otherwise
  1525. //
  1526. // Params: IN pOrder - A pointer to a BMC order.
  1527. // IN destBitsSize - The number of bytes available in
  1528. // pOrder to store the bitmap data.
  1529. // IN pDIBits - A pointer to the bits to be cached.
  1530. // IN bitmapWidth - The "in use" width of the bitmap
  1531. // IN fixedBitmapWidth - The actual width of the bitmap
  1532. // IN bitmapHeight - The height of the bitmap
  1533. // IN numBytes - The number of bytes in the bitmap.
  1534. // OUT pCache - The cache that we put the bits into.
  1535. // OUT pCacheIndex - The cache index within *pCache at
  1536. // which we cached the data.
  1537. // OUT pIsNewEntry - TRUE if we added a new cache entry,
  1538. // FALSE if we matched an existing entry.
  1539. //
  1540. // Operation: pOrder is only filled in if *pIsNewEntry is FALSE.
  1541. //
  1542. //
  1543. BOOL ASHost::SBCCacheBits
  1544. (
  1545. LPINT_ORDER pOrder,
  1546. UINT destBitsSize,
  1547. LPBYTE pDIBits,
  1548. UINT bitmapWidth,
  1549. UINT fixedBitmapWidth,
  1550. UINT bitmapHeight,
  1551. UINT numBytes,
  1552. UINT * pCache,
  1553. UINT * pCacheIndex,
  1554. LPBOOL pIsNewEntry
  1555. )
  1556. {
  1557. BOOL cachedOK = FALSE;
  1558. UINT cacheIndex;
  1559. UINT i;
  1560. LPBYTE pCompressed;
  1561. UINT compressedSize;
  1562. BOOL compressed;
  1563. PBMC_DIB_ENTRY pEntry;
  1564. PBMC_DIB_CACHE pCacheHdr;
  1565. PBMC_BITMAP_BITS_ORDER_R2 pBitsOrderR2;
  1566. PBMC_BITMAP_BITS_DATA pBmcData;
  1567. LPBYTE pDestBits;
  1568. DebugEntry(ASHost::SBCCacheBits);
  1569. pBmcData = (PBMC_BITMAP_BITS_DATA)(pOrder->abOrderData);
  1570. pBitsOrderR2 = (PBMC_BITMAP_BITS_ORDER_R2)pBmcData;
  1571. //
  1572. // Get a pointer to where the bitmap data starts in the order. This
  1573. // depends on whether it is an R1 or an R2 bitmap bits order.
  1574. //
  1575. pDestBits = pBitsOrderR2->data;
  1576. //
  1577. // Before we can select a cache entry we need to compress the bits.
  1578. // This therefore mandates a memcpy into the cache entry when we come
  1579. // to add it. The saving in memory by storing the bits compressed
  1580. // makes it all worthwhile.
  1581. //
  1582. // Compress the bitmap data. At this stage we don't know whether the
  1583. // bitmap will compress well or not, so allow cells that are larger
  1584. // than our maximum cell size. The largest we expect to see is 120*120*
  1585. // 24.
  1586. //
  1587. compressedSize = destBitsSize;
  1588. if (m_pShare->BC_CompressBitmap(pDIBits, pDestBits, &compressedSize,
  1589. fixedBitmapWidth, bitmapHeight, m_usrSendingBPP,
  1590. NULL ) &&
  1591. (compressedSize < numBytes))
  1592. {
  1593. TRACE_OUT(( "Compressed bmp data from %u bytes to %u bytes",
  1594. numBytes,
  1595. compressedSize));
  1596. compressed = TRUE;
  1597. pCompressed = pDestBits;
  1598. }
  1599. else
  1600. {
  1601. //
  1602. // The bitmap could not be compressed, or bitmap compression is not
  1603. // enabled. Send the bitmap uncompressed.
  1604. //
  1605. compressed = FALSE;
  1606. compressedSize = numBytes;
  1607. pCompressed = pDIBits;
  1608. }
  1609. //
  1610. // Make sure that the data will fit into the order. Do this after
  1611. // compression since it is possible that the uncompressed data will not
  1612. // fit, but the compressed version will.
  1613. //
  1614. if (compressedSize > destBitsSize)
  1615. {
  1616. WARNING_OUT(( "Data (%d bytes) does not fit into order (%d bytes)",
  1617. compressedSize,
  1618. destBitsSize));
  1619. DC_QUIT;
  1620. }
  1621. //
  1622. // Select the cache based on the compressed size - we pass in the
  1623. // sub-bitmap dimensions for R1 caching; R2 caching just uses the
  1624. // total size of the bits.
  1625. //
  1626. if (!SBCSelectCache(compressedSize + sizeof(BMC_DIB_ENTRY) - 1, pCache))
  1627. {
  1628. TRACE_OUT(( "No cache selected"));
  1629. DC_QUIT;
  1630. }
  1631. else
  1632. {
  1633. TRACE_OUT(( "Selected cache %d", *pCache));
  1634. }
  1635. //
  1636. // Find a free cache entry in our selected cache
  1637. //
  1638. // We arrange that our transmit cache is always one greater than the
  1639. // negotiated cache size so that we should never fail to find a free
  1640. // array entry. Once we have fully populated our Tx cache we will
  1641. // always find the free entry as the one last given back to us by CH.
  1642. // Note the scan to <= sbcTxCache[pmNumTxCacheEntries is NOT a mistake.
  1643. //
  1644. pCacheHdr = &(m_asbcBmpCaches[*pCache]);
  1645. if (pCacheHdr->data == NULL)
  1646. {
  1647. ERROR_OUT(( "Asked to cache when no cache allocated"));
  1648. DC_QUIT;
  1649. }
  1650. //
  1651. // If the cache has returned an entry to us then use that without
  1652. // having to scan. This will be the default mode for adding entries
  1653. // to a fully populated cache.
  1654. //
  1655. if (pCacheHdr->freeEntry != NULL)
  1656. {
  1657. pEntry = pCacheHdr->freeEntry;
  1658. pCacheHdr->freeEntry = NULL;
  1659. TRACE_OUT(( "Cache fully populated - using entry 0x%08x", pEntry));
  1660. }
  1661. else
  1662. {
  1663. //
  1664. // We are in the process of feeding the cache so we need to search
  1665. // for a free entry
  1666. //
  1667. pEntry = (PBMC_DIB_ENTRY)(pCacheHdr->data);
  1668. for (i=0 ; i < pCacheHdr->cEntries ; i++)
  1669. {
  1670. if (!pEntry->inUse)
  1671. {
  1672. break;
  1673. }
  1674. pEntry = (PBMC_DIB_ENTRY)(((LPBYTE)pEntry) + pCacheHdr->cSize);
  1675. }
  1676. //
  1677. // We should never run out of free entries, but cope with it
  1678. //
  1679. if (i == pCacheHdr->cEntries)
  1680. {
  1681. ERROR_OUT(( "All Tx DIB cache entries in use"));
  1682. DC_QUIT;
  1683. }
  1684. }
  1685. //
  1686. // Set up the DIB entry for caching
  1687. //
  1688. pEntry->inUse = TRUE;
  1689. pEntry->cx = (TSHR_UINT16)bitmapWidth;
  1690. pEntry->cxFixed = (TSHR_UINT16)fixedBitmapWidth;
  1691. pEntry->cy = (TSHR_UINT16)bitmapHeight;
  1692. pEntry->bpp = (TSHR_UINT16)m_usrSendingBPP;
  1693. pEntry->cBits = numBytes;
  1694. pEntry->bCompressed = (BYTE)compressed;
  1695. pEntry->cCompressed = compressedSize;
  1696. memcpy(pEntry->bits, pCompressed, compressedSize);
  1697. //
  1698. // Now cache the data
  1699. //
  1700. if (CH_SearchAndCacheData(pCacheHdr->handle,
  1701. (LPBYTE)pEntry,
  1702. sizeof(BMC_DIB_ENTRY) + compressedSize - 1,
  1703. 0,
  1704. &cacheIndex))
  1705. {
  1706. //
  1707. // The sub-bitmap is already in the cache
  1708. //
  1709. *pCacheIndex = cacheIndex;
  1710. TRACE_OUT(( "Bitmap already cached %u:%u cx(%d) cy(%d)",
  1711. *pCache,
  1712. *pCacheIndex,
  1713. bitmapWidth,
  1714. bitmapHeight));
  1715. *pIsNewEntry = FALSE;
  1716. //
  1717. // Free up the entry we just created
  1718. //
  1719. pEntry->inUse = FALSE;
  1720. }
  1721. else
  1722. {
  1723. *pCacheIndex = cacheIndex;
  1724. TRACE_OUT(( "Cache entry at 0x%08x now in use", pEntry));
  1725. TRACE_OUT(( "New cache entry %u:%u cx(%d) cy(%d)",
  1726. *pCache,
  1727. *pCacheIndex,
  1728. bitmapWidth,
  1729. bitmapHeight));
  1730. *pIsNewEntry = TRUE;
  1731. pEntry->iCacheIndex = (TSHR_UINT16)*pCacheIndex;
  1732. }
  1733. //
  1734. // We've got the bits into the cache. If the cache attempt added a
  1735. // cache entry we must fill in the bitmap cache order.
  1736. //
  1737. if (*pIsNewEntry)
  1738. {
  1739. //
  1740. // Fill in the order details.
  1741. //
  1742. // Remember that we have to fill in the order size into the
  1743. // INT_ORDER_HEADER as well as filling in the bitmap bits order
  1744. // header. When doing this, adjust for the number of bitmap bits
  1745. // which are included in the bitmap bits order header.
  1746. //
  1747. pOrder->OrderHeader.Common.fOrderFlags = OF_PRIVATE;
  1748. if (compressed)
  1749. {
  1750. pBmcData->bmcPacketType = BMC_PT_BITMAP_BITS_COMPRESSED;
  1751. }
  1752. else
  1753. {
  1754. pBmcData->bmcPacketType = BMC_PT_BITMAP_BITS_UNCOMPRESSED;
  1755. //
  1756. // The data is not compressed, so copy the uncompressed data
  1757. // into the order. In the case where we compressed the data
  1758. // successfully, we did so directly into the order, so the
  1759. // compressed bits are already there.
  1760. //
  1761. memcpy(pDestBits, pDIBits, compressedSize);
  1762. }
  1763. pBmcData->cacheID = (BYTE)*pCache;
  1764. pBmcData->cxSubBitmapWidth = (TSHR_UINT8)fixedBitmapWidth;
  1765. pBmcData->cySubBitmapHeight = (TSHR_UINT8)bitmapHeight;
  1766. pBmcData->bpp = (TSHR_UINT8)m_usrSendingBPP;
  1767. pBmcData->cbBitmapBits = (TSHR_UINT16)compressedSize;
  1768. //
  1769. // The iCacheEntryR1 field is unused for R2 - we use
  1770. // iCacheEntryR2 instead.
  1771. //
  1772. pBmcData->iCacheEntryR1 = 0;
  1773. pBitsOrderR2->iCacheEntryR2 = (TSHR_UINT16)*pCacheIndex;
  1774. pOrder->OrderHeader.Common.cbOrderDataLength =
  1775. (compressedSize
  1776. + sizeof(BMC_BITMAP_BITS_ORDER_R2)
  1777. - sizeof(pBitsOrderR2->data));
  1778. }
  1779. cachedOK = TRUE;
  1780. DC_EXIT_POINT:
  1781. DebugExitBOOL(ASHost::SBCCacheBits, cachedOK);
  1782. return(cachedOK);
  1783. }
  1784. //
  1785. //
  1786. // Name: SBCAddToFastPath
  1787. //
  1788. // Purpose: Add a bitmap to the fast path
  1789. //
  1790. // Returns: Nothing
  1791. //
  1792. // Params: IN majorInfo - The major caching info passed up from
  1793. // the driver (the bitmap ID)
  1794. // IN minorInfo - The minor caching info passed up from
  1795. // the driver (the bitmap revision number)
  1796. // IN majorPalette - The major palette info passed up from
  1797. // the driver (the XLATEOBJ)
  1798. // IN minorPalette - The minor palette info passed up from
  1799. // the driver (the XLATEOBJ iUniq)
  1800. // IN srcX - The x coord of the source of the Blt
  1801. // IN srcY - The y coord of the source of the Blt
  1802. // IN width - The width of the area being Blted
  1803. // IN height - The height of the area being Blted
  1804. // IN cache - The cache the bits were placed in
  1805. // IN cacheIndex - The index at which the bits were placed
  1806. // in the cache
  1807. // IN colorCacheIndex - The index in the color table cache of
  1808. // the color table associated with the bits
  1809. //
  1810. //
  1811. void ASHost::SBCAddToFastPath
  1812. (
  1813. UINT_PTR majorInfo,
  1814. UINT minorInfo,
  1815. UINT_PTR majorPalette,
  1816. UINT minorPalette,
  1817. int srcX,
  1818. int srcY,
  1819. UINT width,
  1820. UINT height,
  1821. UINT cache,
  1822. UINT cacheIndex,
  1823. UINT colorCacheIndex
  1824. )
  1825. {
  1826. LPSBC_FASTPATH_ENTRY pEntry;
  1827. DebugEntry(ASHost::SBCAddToFastPath);
  1828. //
  1829. // First get a free entry
  1830. //
  1831. pEntry = (LPSBC_FASTPATH_ENTRY)COM_BasedListFirst(&m_sbcFastPath->freeList,
  1832. FIELD_OFFSET(SBC_FASTPATH_ENTRY, list));
  1833. if (pEntry == NULL)
  1834. {
  1835. //
  1836. // There are no entries in the free list, so we have to use the
  1837. // oldest entry in the used list. The used list is stored in MRU
  1838. // order, so we just have to get the last item in the list.
  1839. //
  1840. pEntry = (LPSBC_FASTPATH_ENTRY)COM_BasedListLast(&m_sbcFastPath->usedList,
  1841. FIELD_OFFSET(SBC_FASTPATH_ENTRY, list));
  1842. TRACE_OUT(( "Evicting fast path info for %x %x (%d, %d)",
  1843. pEntry->majorInfo,
  1844. pEntry->minorInfo,
  1845. pEntry->srcX,
  1846. pEntry->srcY));
  1847. }
  1848. //
  1849. // Remove the entry from its current list
  1850. //
  1851. COM_BasedListRemove(&pEntry->list);
  1852. //
  1853. // Now fill in the details
  1854. //
  1855. pEntry->majorInfo = majorInfo;
  1856. pEntry->minorInfo = minorInfo;
  1857. pEntry->majorPalette = majorPalette;
  1858. pEntry->minorPalette = minorPalette;
  1859. pEntry->srcX = srcX;
  1860. pEntry->srcY = srcY;
  1861. pEntry->width = width;
  1862. pEntry->height = height;
  1863. pEntry->cache = (WORD)cache;
  1864. pEntry->cacheIndex = (WORD)cacheIndex;
  1865. pEntry->colorIndex = (WORD)colorCacheIndex;
  1866. //
  1867. // Finally, add the entry to the front of the used list
  1868. //
  1869. TRACE_OUT(( "Adding fast path info for %x %x (%d, %d)",
  1870. pEntry->majorInfo,
  1871. pEntry->minorInfo,
  1872. pEntry->srcX,
  1873. pEntry->srcY));
  1874. COM_BasedListInsertAfter(&m_sbcFastPath->usedList, &pEntry->list);
  1875. DebugExitVOID(ASHost::SBCAddToFastPath);
  1876. }
  1877. //
  1878. //
  1879. // Name: SBCFindInFastPath
  1880. //
  1881. // Purpose: Check to see if a bitmap with the given attributes is in the
  1882. // SBC fast path. If so, return the cache info for the bitmap.
  1883. //
  1884. // Returns: TRUE if the bitmap is in the fast path, FALSE if not.
  1885. //
  1886. // Params: IN majorInfo - The major caching info passed up from
  1887. // the driver (the bitmap ID)
  1888. // IN minorInfo - The minor caching info passed up from
  1889. // the driver (the bitmap revision
  1890. // number)
  1891. // IN majorPalette - The major palette info passed up from
  1892. // the driver (the XLATEOBJ)
  1893. // IN minorPalette - The minor palette info passed up from
  1894. // the driver (the XLATEOBJ iUniq)
  1895. // IN srcX - The x coord of the source of the Blt
  1896. // IN srcY - The y coord of the source of the Blt
  1897. // IN width - The width of the area being Blted
  1898. // IN height - The height of the area being Blted
  1899. // OUT pCache - The cache the bits were placed in
  1900. // OUT pCacheIndex - The index at which the bits were
  1901. // placed in the cache
  1902. // OUT pColorCacheIndex - The index in the color table cache of
  1903. // the color table associated with the
  1904. // bits
  1905. //
  1906. // Operation: The contents of pCache, pCacheIndex and pColorCacheIndex
  1907. // are only valid on return if the function returns TRUE.
  1908. //
  1909. //
  1910. BOOL ASHost::SBCFindInFastPath
  1911. (
  1912. UINT_PTR majorInfo,
  1913. UINT minorInfo,
  1914. UINT_PTR majorPalette,
  1915. UINT minorPalette,
  1916. int srcX,
  1917. int srcY,
  1918. UINT width,
  1919. UINT height,
  1920. UINT * pCache,
  1921. UINT * pCacheIndex,
  1922. UINT * pColorCacheIndex
  1923. )
  1924. {
  1925. BOOL found = FALSE;
  1926. LPSBC_FASTPATH_ENTRY pEntry;
  1927. LPSBC_FASTPATH_ENTRY pNextEntry;
  1928. DebugEntry(ASHost::SBCFindInFastPath);
  1929. //
  1930. // Traverse the in use list looking for a match on the parameters
  1931. // passed in.
  1932. //
  1933. pEntry = (LPSBC_FASTPATH_ENTRY)COM_BasedListFirst(&m_sbcFastPath->usedList, FIELD_OFFSET(SBC_FASTPATH_ENTRY, list));
  1934. while (pEntry != NULL)
  1935. {
  1936. if ((pEntry->majorInfo == majorInfo) &&
  1937. (pEntry->minorInfo == minorInfo) &&
  1938. (pEntry->majorPalette == majorPalette) &&
  1939. (pEntry->minorPalette == minorPalette) &&
  1940. (pEntry->srcX == srcX) &&
  1941. (pEntry->srcY == srcY) &&
  1942. (pEntry->width == width) &&
  1943. (pEntry->height == height))
  1944. {
  1945. //
  1946. // We've found a match - hurrah ! Fill in the return info.
  1947. //
  1948. TRACE_OUT(( "Hit for %x %x (%d, %d) cache %d",
  1949. pEntry->majorInfo,
  1950. pEntry->minorInfo,
  1951. pEntry->srcX,
  1952. pEntry->srcY,
  1953. pEntry->cache,
  1954. pEntry->cacheIndex));
  1955. found = TRUE;
  1956. *pCache = pEntry->cache;
  1957. *pCacheIndex = pEntry->cacheIndex;
  1958. *pColorCacheIndex = pEntry->colorIndex;
  1959. //
  1960. // We order the used list in MRU order, so remove the entry
  1961. // from its current position and add it at the head of the used
  1962. // list.
  1963. //
  1964. COM_BasedListRemove(&pEntry->list);
  1965. COM_BasedListInsertAfter(&m_sbcFastPath->usedList, &pEntry->list);
  1966. //
  1967. // Got a match, so we can break out of the while loop
  1968. //
  1969. break;
  1970. }
  1971. else if ((pEntry->majorInfo == majorInfo) &&
  1972. (pEntry->minorInfo != minorInfo))
  1973. {
  1974. //
  1975. // We have been given a bitmap which we have seen before, but
  1976. // the revision number has changed i.e. the bitmap has been
  1977. // updated (majorInfo identifies the bitmap, and minorInfo
  1978. // identifies the revision number of that bitmap - it is
  1979. // incremented every time the bitmap is changed).
  1980. //
  1981. // We have to remove all entries from the used list which
  1982. // reference this bitmap. We can start from the current
  1983. // position since we know that we can't have an entry for this
  1984. // bitmap earlier in the list, but we have to be careful to get
  1985. // the next entry in the list before removing an entry.
  1986. //
  1987. TRACE_OUT(( "Bitmap %x updated - removing references",
  1988. pEntry->majorInfo));
  1989. pNextEntry = pEntry;
  1990. while (pNextEntry != NULL)
  1991. {
  1992. pEntry = pNextEntry;
  1993. pNextEntry = (LPSBC_FASTPATH_ENTRY)COM_BasedListNext(&m_sbcFastPath->usedList,
  1994. pNextEntry, FIELD_OFFSET(SBC_FASTPATH_ENTRY, list));
  1995. if (pEntry->majorInfo == majorInfo)
  1996. {
  1997. COM_BasedListRemove(&pEntry->list);
  1998. COM_BasedListInsertAfter(&m_sbcFastPath->freeList,
  1999. &pEntry->list);
  2000. }
  2001. }
  2002. //
  2003. // We know we wont find a match, so we can break out of the
  2004. // while loop
  2005. //
  2006. break;
  2007. }
  2008. pEntry = (LPSBC_FASTPATH_ENTRY)COM_BasedListNext(&m_sbcFastPath->usedList, pEntry,
  2009. FIELD_OFFSET(SBC_FASTPATH_ENTRY, list));
  2010. }
  2011. DebugExitBOOL(ASShare::SBCFindInFastPath, found);
  2012. return(found);
  2013. }
  2014. //
  2015. // SBC_CacheEntryRemoved()
  2016. //
  2017. void ASHost::SBC_CacheEntryRemoved
  2018. (
  2019. UINT cache,
  2020. UINT cacheIndex
  2021. )
  2022. {
  2023. LPSBC_FASTPATH_ENTRY pEntry;
  2024. LPSBC_FASTPATH_ENTRY pNextEntry;
  2025. DebugEntry(ASHost::SBC_CacheEntryRemoved);
  2026. ASSERT(m_sbcFastPath);
  2027. //
  2028. // An entry has been removed from the cache. If we have this entry in
  2029. // our fast path, we have to remove it.
  2030. //
  2031. // Just traverse the used list looking for an entry with matching cache
  2032. // and cacheIndex. Note that there may be more than one entry - if the
  2033. // source bitmap has a repeating image, we will get a match on the bits
  2034. // when we cache different areas of the bitmap.
  2035. //
  2036. pNextEntry = (LPSBC_FASTPATH_ENTRY)COM_BasedListFirst(&m_sbcFastPath->usedList,
  2037. FIELD_OFFSET(SBC_FASTPATH_ENTRY, list));
  2038. while (pNextEntry != NULL)
  2039. {
  2040. pEntry = pNextEntry;
  2041. pNextEntry = (LPSBC_FASTPATH_ENTRY)COM_BasedListNext(&m_sbcFastPath->usedList,
  2042. pNextEntry, FIELD_OFFSET(SBC_FASTPATH_ENTRY, list));
  2043. if ((pEntry->cache == cache) && (pEntry->cacheIndex == cacheIndex))
  2044. {
  2045. //
  2046. // Move the entry to the free list
  2047. //
  2048. TRACE_OUT(("Fast path entry %x %x (%d, %d) evicted from cache",
  2049. pEntry->majorInfo,
  2050. pEntry->minorInfo,
  2051. pEntry->srcX,
  2052. pEntry->srcY));
  2053. COM_BasedListRemove(&pEntry->list);
  2054. COM_BasedListInsertAfter(&m_sbcFastPath->freeList,
  2055. &pEntry->list);
  2056. }
  2057. }
  2058. DebugExitVOID(ASHost::SBC_CacheEntryRemoved);
  2059. }