This structure specifies a point relative to the virtual-desktop origin.
        public void RDPEGFX_CacheManagement_Negative_CacheToSurface_InexistentCacheSlot()
        {
            this.TestSite.Log.Add(LogEntryKind.Comment, "Do capability exchange.");
            RDPEGFX_CapabilityExchange();

            // Create a surface & output a surface
            RDPGFX_RECT16 surfRect = RdpegfxTestUtility.ConvertToRect(RdpegfxTestUtility.surfPos, RdpegfxTestUtility.largeSurfWidth, RdpegfxTestUtility.largeSurfHeight);
            Surface surf = this.rdpegfxAdapter.CreateAndOutputSurface(surfRect, PixelFormat.PIXEL_FORMAT_ARGB_8888);
            this.TestSite.Assert.IsNotNull(surf, "Surface {0} is created", surf.Id);

            this.TestSite.Log.Add(LogEntryKind.Comment, "Set the test type to {0}.", RdpegfxNegativeTypes.CacheManagement_CacheToSurface_InexistentCacheSlot);
            this.rdpegfxAdapter.SetTestType(RdpegfxNegativeTypes.CacheManagement_CacheToSurface_InexistentCacheSlot);

            // Build mutliple cache to surface messages to cover the surface by cacheRect
            ushort cacheW = (ushort)(RdpegfxTestUtility.largeCacheRect.right - RdpegfxTestUtility.largeCacheRect.left);
            ushort cacheH = (ushort)(RdpegfxTestUtility.largeCacheRect.bottom - RdpegfxTestUtility.largeCacheRect.top);

            ushort currRectTop = 0;

            // DestPointList is a list of positions in destination surface where the bitmap cache will copy to
            List<RDPGFX_POINT16> destPointList = new List<RDPGFX_POINT16>();
            while (currRectTop < surf.Height)
            {
                ushort currRectLeft = 0;
                while (currRectLeft < surf.Width)
                {
                    RDPGFX_POINT16 pos = new RDPGFX_POINT16(currRectLeft, currRectTop);
                    destPointList.Add(pos);
                    currRectLeft += cacheW;
                }
                currRectTop += cacheH;
            }

            // Trigger the client to copy cached bitmap from an inexsitent cache slot to destination surface
            this.TestSite.Log.Add(LogEntryKind.Comment, "Trigger the client to copy cached bitmap from an inexistent cache slot to destination surface.");
            uint fid = this.rdpegfxAdapter.FillSurfaceByCachedBitmap(surf, RdpegfxTestUtility.largeCacheRect, RdpegfxTestUtility.cacheKey, destPointList.ToArray(), null, RdpegfxTestUtility.fillColorRed);

            this.TestSite.Log.Add(LogEntryKind.Comment, "Expect SUT to drop the connection");
            bool bDisconnected = this.rdpbcgrAdapter.WaitForDisconnection(waitTime);
            this.TestSite.Assert.IsTrue(bDisconnected, "RDP client should terminate the connection when invalid message received.");
        }
        /// <summary>
        /// Copy bitmap data from the bitmap cache to a destination surface.
        /// </summary>
        /// <param name="cacheSlot"></param>
        /// <param name="surfaceId"></param>
        /// <param name="destPts"></param>
        public void CacheToSurface(ushort cacheSlot, ushort surfaceId, RDPGFX_POINT16[] destPts)
        {
            if (surfaceDic.ContainsKey(surfaceId) && bitmapCache.ContainsKey(cacheSlot))
            {
                if (destPts != null && destPts.Length > 0)
                {
                    Surface surfaceDest = surfaceDic[surfaceId];
                    CacheItem cacheItem = bitmapCache[cacheSlot];

                    foreach (RDPGFX_POINT16 destPt in destPts)
                    {
                        surfaceDest.DrawImage(cacheItem.Image, destPt.x, destPt.y);
                    }
                }
            }
        }
        public void RDPEGFX_CacheManagement_PositiveTest_CacheToSurface_DestRectsBorderOverlapSurface()
        {
            // Init for capability exchange
            RDPEGFX_CapabilityExchange();

            // Create a surface
            this.TestSite.Log.Add(LogEntryKind.Comment, "Create a Surface.");
            RDPGFX_RECT16 surfRect = RdpegfxTestUtility.ConvertToRect(RdpegfxTestUtility.surfPos, RdpegfxTestUtility.surfWidth, RdpegfxTestUtility.surfHeight);
            Surface surf = this.rdpegfxAdapter.CreateAndOutputSurface(surfRect, PixelFormat.PIXEL_FORMAT_ARGB_8888);
            this.TestSite.Assert.IsNotNull(surf, "Surface {0} is created", surf.Id);

            ushort cacheW = (ushort)(RdpegfxTestUtility.cacheRect.right - RdpegfxTestUtility.cacheRect.left);
            ushort cacheH = (ushort)(RdpegfxTestUtility.cacheRect.bottom - RdpegfxTestUtility.cacheRect.top);

            List<RDPGFX_POINT16> destPointList = new List<RDPGFX_POINT16>();
            RDPGFX_POINT16 pos = new RDPGFX_POINT16(
                (ushort)(RdpegfxTestUtility.surfWidth - cacheW),
                (ushort)(RdpegfxTestUtility.surfHeight - cacheH));
            destPointList.Add(pos);

            this.TestSite.Log.Add(LogEntryKind.Comment, "Copy a rect to cache; and copy the cached rect to surface.");
            uint fid = this.rdpegfxAdapter.FillSurfaceByCachedBitmap(surf, RdpegfxTestUtility.cacheRect, RdpegfxTestUtility.cacheKey, destPointList.ToArray(), null, RdpegfxTestUtility.fillColorRed);
            this.TestSite.Log.Add(LogEntryKind.Debug, "Surface is filled by cached bitmap in frame: {0}.", fid);

            this.rdpegfxAdapter.ExpectFrameAck(fid);

            this.TestSite.Log.Add(LogEntryKind.Comment, "Verify output on SUT Display if the verifySUTDisplay entry in PTF config is true.");
            this.VerifySUTDisplay(false, surfRect);

            // Delete the surface after wait 3 seconds.
            this.rdpegfxAdapter.DeleteSurface(surf.Id);
            this.TestSite.Log.Add(LogEntryKind.Debug, "Surface {0} is deleted", surf.Id);
        }
        /// <summary>
        /// Encode a bitmap data by RemoteFX codec.
        /// </summary>
        /// <param name="image"> The bitmap image to be sent </param>
        /// <param name="opMode"> Indicate Operational Mode.</param>
        /// <param name="entropy"> Indicate Entropy Algorithm.</param>
        /// <param name="imgPos"> The top-left position of bitmap image relative to surface</param>
        /// <param name="sId"> The surface Id that bitmap image is sent to </param>
        /// <returns> A dictionary with frameId and byte stream frame pair </returns>
        public Dictionary<uint, byte[]> RemoteFXCodecEncode(System.Drawing.Image image, OperationalMode opMode, EntropyAlgorithm entropy,
            RDPGFX_POINT16 imgPos, ushort sId, PixelFormat pixFormat)
        {
            if (image == null) return null;

            Dictionary<uint, byte[]> frDict = new Dictionary<uint, byte[]>();   // Save encoded frames for one tile

            TileImage[] tileImageArr = RdprfxTileUtils.SplitToTileImage(image, RdprfxServer.TileSize, RdprfxServer.TileSize);

            for (uint index = 0; index < tileImageArr.Length; index++)
            {
                byte[] tileBitmap = this.PackRfxTileImage(index, opMode, entropy, tileImageArr[index].image);
                ushort tileLeft = (ushort)(imgPos.x + tileImageArr[index].x);
                ushort tileTop = (ushort)(imgPos.y + tileImageArr[index].y);
                RDPGFX_RECT16 tileRect = new RDPGFX_RECT16(tileLeft, tileTop,
                                                            (ushort)(tileLeft + tileImageArr[index].image.Width),
                                                            (ushort)(tileTop + tileImageArr[index].image.Height));

                uint fid = MakeStartFramePdu();
                MakeWireToSurfacePdu1(sId, CodecType.RDPGFX_CODECID_CAVIDEO, pixFormat, tileRect, tileBitmap);
                MakeEndFramePdu(fid);

                if (this.bcgrAdapter.SimulatedScreen != null)
                {
                    this.bcgrAdapter.SimulatedScreen.RenderRemoteFXTile(sId, tileRect);
                }

                frDict.Add(fid, EncodePdusToSent());
            }

            return frDict;
        }
        /// <summary>
        /// Method to copy bitmap of a rectangle in a surface to other position in another surface
        /// </summary>
        /// <param name="surf">The source surface where the rectangle to be copied.</param>
        /// <param name="srcRect">The rectangle to be copied.</param>
        /// <param name="fillColor">The color of rectangle to be filled.</param>
        /// <param name="surfDest">The destination surface where the rectangle is copied to.</param>
        /// <param name="destPos">The position array that rectangle is copied to.</param>
        /// <returns> Frame Id </returns>
        public uint InterSurfaceCopy(Surface surfSrc, RDPGFX_RECT16 srcRect, RDPGFX_COLOR32 fillColor, Surface surfDest, RDPGFX_POINT16[] destPos)
        {
            uint fid = MakeStartFramePdu();
            RDPGFX_RECT16[] rects = { srcRect };
            MakeSolidFillPdu(surfSrc.Id, fillColor, rects);
            MakeSurfaceToSurfacePdu(surfSrc.Id, surfDest.Id, srcRect, destPos);
            if (currentTestType != RdpegfxNegativeTypes.SurfaceManagement_InterSurfaceCopy_DestPtsCount_Mismatch)
            {
                MakeEndFramePdu(fid);
            }

            PackAndSendServerPdu();

            return fid;
        }
        /// <summary>
        /// Method to implement CacheToSurface functionality.
        /// </summary>
        /// <param name="surf">The surface to be filled.</param>
        /// <param name="cacheSlot">Cache slot of bitmap</param>
        /// <param name="destPoints">This is used to specify destination points of source rectangle bitmap to be copied</param>
        /// <returns>Frame Id</returns>
        public uint FillSurfaceByCachedBitmap(Surface surf, ushort cacheSlot, RDPGFX_POINT16[] destPoints)
        {
            uint fid = MakeStartFramePdu();
            MakeCacheToSurfacePdu(cacheSlot, surf.Id, destPoints);

            MakeEndFramePdu(fid);

            PackAndSendServerPdu();
            return fid;
        }
        /// <summary>
        /// Method to make a cache to surface Pdu
        /// </summary>
        /// <param name="slot">This is used to indicate a cache slot.</param>
        /// <param name="sid">This is used to indicate the destination surface id.</param>
        /// <param name="destPoints">This is used to specify destination points of source rectangle bitmap to be copied </param>
        void MakeCacheToSurfacePdu(ushort slot, ushort sid, RDPGFX_POINT16[] destPoints)
        {
            RDPGFX_CACHE_TO_SURFACE cacheToSurface = egfxServer.CreateCacheToSurfacePdu(slot, sid, destPoints);
            AddPdusToBuffer(cacheToSurface);

            if (this.bcgrAdapter.SimulatedScreen != null)
            {
                this.bcgrAdapter.SimulatedScreen.CacheToSurface(slot, sid, destPoints);
            }
        }
 /// <summary>
 /// Add more position in destination surface to be copied.
 /// </summary>
 /// <param name="destPosition">This is used to specify a destination position of source rectangle bitmap to be copied.</param>
 public void AddDestPosition(RDPGFX_POINT16 destPosition)
 {
     this.destPtsList.Add(destPosition);
     this.destPtsCount++;
     this.Header.pduLength += (uint)Marshal.SizeOf(destPosition);
 }
        public void RDPEGFX_CacheManagement_PositiveTest_SurfaceToCache_UpdateCache()
        {
            ushort cacheSlot = 1;
            // Init for capability exchange
            RDPEGFX_CapabilityExchange();

            // Create a surface
            this.TestSite.Log.Add(LogEntryKind.Comment, "Create a Surface.");
            RDPGFX_RECT16 surfRect = RdpegfxTestUtility.ConvertToRect(RdpegfxTestUtility.surfPos, RdpegfxTestUtility.surfWidth, RdpegfxTestUtility.surfHeight);
            Surface surf = this.rdpegfxAdapter.CreateAndOutputSurface(surfRect, PixelFormat.PIXEL_FORMAT_ARGB_8888);
            this.TestSite.Assert.IsNotNull(surf, "Surface {0} is created", surf.Id);

            this.TestSite.Log.Add(LogEntryKind.Comment, "Cache a rect of Surface to cache.");
            uint fid = this.rdpegfxAdapter.CacheSurface(surf, RdpegfxTestUtility.cacheRect, RdpegfxTestUtility.cacheKey, cacheSlot, RdpegfxTestUtility.fillColorRed);
            this.TestSite.Log.Add(LogEntryKind.Debug, "Cache a rect in surface, slot is {0}.", cacheSlot);
            this.rdpegfxAdapter.ExpectFrameAck(fid);

            this.TestSite.Log.Add(LogEntryKind.Comment, "Cache a rect of Surface to cache with same cacheSlot.");
            fid = this.rdpegfxAdapter.CacheSurface(surf, RdpegfxTestUtility.cacheRect, RdpegfxTestUtility.cacheKey, cacheSlot, RdpegfxTestUtility.fillColorGreen);
            this.TestSite.Log.Add(LogEntryKind.Debug, "Cache a rect in surface, slot is {0}.", cacheSlot);
            this.rdpegfxAdapter.ExpectFrameAck(fid);

            this.TestSite.Log.Add(LogEntryKind.Comment, "Fill the Surface with cached slot.");
            RDPGFX_POINT16[] destPoints = new RDPGFX_POINT16[] { new RDPGFX_POINT16(RdpegfxTestUtility.cacheRect.right, RdpegfxTestUtility.cacheRect.bottom) };
            fid = this.rdpegfxAdapter.FillSurfaceByCachedBitmap(surf, cacheSlot, destPoints);
            this.rdpegfxAdapter.ExpectFrameAck(fid);

            this.TestSite.Log.Add(LogEntryKind.Comment, "Verify output on SUT Display if the verifySUTDisplay entry in PTF config is true.");
            this.VerifySUTDisplay(false, surfRect);

            // Delete the surface after wait 3 seconds.
            this.rdpegfxAdapter.DeleteSurface(surf.Id);
            this.TestSite.Log.Add(LogEntryKind.Debug, "Surface {0} is deleted", surf.Id);
        }
        public void RDPEGFX_CacheManagement_PositiveTest_SurfaceToCache_SrcRectBorderOverlapSurface()
        {
            ushort maxCacheSlot = RdpegfxTestUtility.maxCacheSlot;

            // Init for capability exchange
            RDPEGFX_CapabilityExchange();

            if (this.isSmallCache)
            {
                maxCacheSlot = RdpegfxTestUtility.maxCacheSlotForSmallCache;
            }

            // Create a surface
            this.TestSite.Log.Add(LogEntryKind.Comment, "Create a Surface.");
            RDPGFX_RECT16 surfRect = RdpegfxTestUtility.ConvertToRect(RdpegfxTestUtility.surfPos, RdpegfxTestUtility.surfWidth, RdpegfxTestUtility.surfHeight);
            Surface surf = this.rdpegfxAdapter.CreateAndOutputSurface(surfRect, PixelFormat.PIXEL_FORMAT_ARGB_8888);
            this.TestSite.Assert.IsNotNull(surf, "Surface {0} is created", surf.Id);

            // Create srcRect, in the bottom-right corner of surface
            RDPGFX_RECT16 srcRect = new RDPGFX_RECT16();
            srcRect.left = (ushort)(RdpegfxTestUtility.surfWidth - RdpegfxTestUtility.smallWidth);
            srcRect.top = (ushort)(RdpegfxTestUtility.surfHeight - RdpegfxTestUtility.smallHeight);
            srcRect.right = RdpegfxTestUtility.surfWidth;
            srcRect.bottom = RdpegfxTestUtility.surfHeight;

            this.TestSite.Log.Add(LogEntryKind.Comment, "Copy a rect to cache; and copy the cached rect to surface.");
            RDPGFX_POINT16[] destPoints = new RDPGFX_POINT16[] { RdpegfxTestUtility.imgPos };
            uint fid = this.rdpegfxAdapter.FillSurfaceByCachedBitmap(surf, srcRect, RdpegfxTestUtility.cacheKey, destPoints, null, RdpegfxTestUtility.fillColorRed);
            this.TestSite.Log.Add(LogEntryKind.Debug, "Surface is filled by cached bitmap in frame: {0}.", fid, maxCacheSlot);

            this.rdpegfxAdapter.ExpectFrameAck(fid);

            this.TestSite.Log.Add(LogEntryKind.Comment, "Verify output on SUT Display if the verifySUTDisplay entry in PTF config is true.");
            this.VerifySUTDisplay(false, surfRect);

            // Delete the surface after wait 3 seconds.
            this.rdpegfxAdapter.DeleteSurface(surf.Id);
            this.TestSite.Log.Add(LogEntryKind.Debug, "Surface {0} is deleted", surf.Id);
        }
        public void RDPEGFX_CacheManagement_PositiveTest_SurfaceToCache_MaxCacheSlot()
        {
            ushort maxCacheSlot = RdpegfxTestUtility.maxCacheSlot;

            // Init for capability exchange
            RDPEGFX_CapabilityExchange();

            if (this.isSmallCache)
            {
                maxCacheSlot = RdpegfxTestUtility.maxCacheSlotForSmallCache;
            }

            // Create a surface
            this.TestSite.Log.Add(LogEntryKind.Comment, "Create a Surface.");
            RDPGFX_RECT16 surfRect = RdpegfxTestUtility.ConvertToRect(RdpegfxTestUtility.surfPos, RdpegfxTestUtility.surfWidth, RdpegfxTestUtility.surfHeight);
            Surface surf = this.rdpegfxAdapter.CreateAndOutputSurface(surfRect, PixelFormat.PIXEL_FORMAT_ARGB_8888);
            this.TestSite.Assert.IsNotNull(surf, "Surface {0} is created", surf.Id);

            List<RDPGFX_POINT16> destPointList = new List<RDPGFX_POINT16>();
            RDPGFX_POINT16 pos = new RDPGFX_POINT16(RdpegfxTestUtility.cacheRect.right, RdpegfxTestUtility.cacheRect.bottom);
            destPointList.Add(pos);

            this.TestSite.Log.Add(LogEntryKind.Comment, "Copy a rect to cache; and copy the cached rect to surface, using max cacheSlot: {0}.", maxCacheSlot);
            uint fid = this.rdpegfxAdapter.FillSurfaceByCachedBitmap(surf, RdpegfxTestUtility.cacheRect, RdpegfxTestUtility.cacheKey, destPointList.ToArray(), maxCacheSlot, RdpegfxTestUtility.fillColorRed);
            this.TestSite.Log.Add(LogEntryKind.Debug, "Surface is filled by cached bitmap in frame: {0}, use max cacheSlot number {1}.", fid, maxCacheSlot);

            this.rdpegfxAdapter.ExpectFrameAck(fid);

            this.TestSite.Log.Add(LogEntryKind.Comment, "Verify output on SUT Display if the verifySUTDisplay entry in PTF config is true.");
            this.VerifySUTDisplay(false, surfRect);

            // Delete the surface after wait 3 seconds.
            this.rdpegfxAdapter.DeleteSurface(surf.Id);
            this.TestSite.Log.Add(LogEntryKind.Debug, "Surface {0} is deleted", surf.Id);
        }
        public void RDPEGFX_CacheManagement_PositiveTest_EvictCache_DeleteCacheSlot()
        {
            ushort cacheSlot = 1;
            // Init for capability exchange
            RDPEGFX_CapabilityExchange();

            // Create a surface
            this.TestSite.Log.Add(LogEntryKind.Comment, "Create a Surface.");
            RDPGFX_RECT16 surfRect = RdpegfxTestUtility.ConvertToRect(RdpegfxTestUtility.surfPos, RdpegfxTestUtility.surfWidth, RdpegfxTestUtility.surfHeight);
            Surface surf = this.rdpegfxAdapter.CreateAndOutputSurface(surfRect, PixelFormat.PIXEL_FORMAT_ARGB_8888);
            this.TestSite.Assert.IsNotNull(surf, "Surface {0} is created", surf.Id);

            this.TestSite.Log.Add(LogEntryKind.Comment, "Fill a rect on surface and cache this rect.");
            uint fid = this.rdpegfxAdapter.CacheSurface(surf, RdpegfxTestUtility.cacheRect, RdpegfxTestUtility.cacheKey, cacheSlot, RdpegfxTestUtility.fillColorRed);
            this.rdpegfxAdapter.ExpectFrameAck(fid);

            this.TestSite.Log.Add(LogEntryKind.Comment, "Evict the cache slot.");
            fid = this.rdpegfxAdapter.EvictCachEntry(cacheSlot);
            this.rdpegfxAdapter.ExpectFrameAck(fid);

            List<RDPGFX_POINT16> destPointList = new List<RDPGFX_POINT16>();
            RDPGFX_POINT16 pos = new RDPGFX_POINT16(RdpegfxTestUtility.cacheRect.right, RdpegfxTestUtility.cacheRect.bottom);
            destPointList.Add(pos);

            this.TestSite.Log.Add(LogEntryKind.Comment, "Copy image from deleted slot.");
            fid = this.rdpegfxAdapter.FillSurfaceByCachedBitmap(surf, cacheSlot, destPointList.ToArray());

            this.TestSite.Log.Add(LogEntryKind.Comment, "Expect SUT to drop the connection");
            bool bDisconnected = this.rdpbcgrAdapter.WaitForDisconnection(waitTime);
            this.TestSite.Assert.IsTrue(bDisconnected, "RDP client should terminate the connection when invalid message received.");
        }
        public void RDPEGFX_CacheManagement_PositiveTest_CacheToSurface_DestRectsOverlapped()
        {
            // Init for capability exchange
            RDPEGFX_CapabilityExchange();

            // Create a surface
            this.TestSite.Log.Add(LogEntryKind.Comment, "Create a Surface.");
            RDPGFX_RECT16 surfRect = RdpegfxTestUtility.ConvertToRect(RdpegfxTestUtility.surfPos, RdpegfxTestUtility.surfWidth, RdpegfxTestUtility.surfHeight);
            Surface surf = this.rdpegfxAdapter.CreateAndOutputSurface(surfRect, PixelFormat.PIXEL_FORMAT_ARGB_8888);
            this.TestSite.Assert.IsNotNull(surf, "Surface {0} is created", surf.Id);

            // Send solid fill request to client to fill a rect to green color
            this.TestSite.Log.Add(LogEntryKind.Comment, "Send solid fill request to client to fill a rect to green color.");
            RDPGFX_RECT16 fillSurfRect = new RDPGFX_RECT16(0, 0, RdpegfxTestUtility.smallWidth, RdpegfxTestUtility.smallHeight);
            RDPGFX_RECT16[] fillRects = { fillSurfRect };  // Relative to surface
            uint fid = this.rdpegfxAdapter.SolidFillSurface(surf, RdpegfxTestUtility.fillColorGreen, fillRects);
            this.rdpegfxAdapter.ExpectFrameAck(fid);

            // Send solid fill request to client to fill a rect to red color
            this.TestSite.Log.Add(LogEntryKind.Comment, "Send solid fill request to client to fill a rect to red color.");
            RDPGFX_RECT16 fillSurfRect2 = new RDPGFX_RECT16(RdpegfxTestUtility.smallWidth, RdpegfxTestUtility.smallHeight, (ushort)(RdpegfxTestUtility.smallWidth * 2), (ushort)(RdpegfxTestUtility.smallHeight * 2));
            RDPGFX_RECT16[] fillRects2 = { fillSurfRect2 };  // Relative to surface
            fid = this.rdpegfxAdapter.SolidFillSurface(surf, RdpegfxTestUtility.fillColorRed, fillRects2);
            this.rdpegfxAdapter.ExpectFrameAck(fid);

            RDPGFX_RECT16 srcRect = new RDPGFX_RECT16(0, 0, (ushort)(RdpegfxTestUtility.smallWidth * 2), (ushort)(RdpegfxTestUtility.smallHeight * 2));
            List<RDPGFX_POINT16> destPointList = new List<RDPGFX_POINT16>();
            RDPGFX_POINT16 pos = new RDPGFX_POINT16((ushort)(RdpegfxTestUtility.smallWidth * 2), (ushort)(RdpegfxTestUtility.smallHeight * 2));
            destPointList.Add(pos);
            pos = new RDPGFX_POINT16((ushort)(RdpegfxTestUtility.smallWidth * 3), (ushort)(RdpegfxTestUtility.smallHeight * 3));
            destPointList.Add(pos);

            this.TestSite.Log.Add(LogEntryKind.Comment, "Copy a rect to cache; and copy the cached rect to surface.");
            fid = this.rdpegfxAdapter.FillSurfaceByCachedBitmap(surf, RdpegfxTestUtility.cacheRect, RdpegfxTestUtility.cacheKey, destPointList.ToArray(), null, null);
            this.TestSite.Log.Add(LogEntryKind.Debug, "Surface is filled by cached bitmap in frame: {0}.", fid);

            this.rdpegfxAdapter.ExpectFrameAck(fid);

            this.TestSite.Log.Add(LogEntryKind.Comment, "Verify output on SUT Display if the verifySUTDisplay entry in PTF config is true.");
            RDPGFX_RECT16 verifyRect = new RDPGFX_RECT16(
                (ushort)(RdpegfxTestUtility.smallWidth * 2), (ushort)(RdpegfxTestUtility.smallHeight * 2),
                (ushort)(RdpegfxTestUtility.smallWidth * 5), (ushort)(RdpegfxTestUtility.smallHeight * 5));
            this.VerifySUTDisplay(false, surfRect);

            // Delete the surface after wait 3 seconds.
            this.rdpegfxAdapter.DeleteSurface(surf.Id);
            this.TestSite.Log.Add(LogEntryKind.Debug, "Surface {0} is deleted", surf.Id);
        }
        /// <summary>
        /// Render a batch of clear codec images
        /// </summary>
        /// <param name="surfaceId"></param>
        /// <param name="startGlyphIdx"></param>
        /// <param name="startGlyphPos"></param>
        /// <param name="glyphNum"></param>
        /// <param name="glyph"></param>
        public void RenderClearCodecBatch(ushort surfaceId, ushort startGlyphIdx, RDPGFX_POINT16 startGlyphPos, ushort glyphNum, Image glyph)
        {
            ushort glyphIdx = startGlyphIdx;

            if (this.surfaceDic.ContainsKey(surfaceId))
            {
                Surface sur = surfaceDic[surfaceId];
                for (int i = 0; i < glyphNum; i++)
                {
                    sur.DrawImage(glyph, (ushort)(startGlyphPos.x + i), startGlyphPos.y);
                    this.clearCodecGlyphStorage.Add(glyphIdx++, glyph);
                }
            }
        }
        private void RDPEGFX_CacheManagement(DynamicVC_TransportType transport, bool isSoftSync)
        {
            // Check if SUT supports Soft Sync.
            if(isSoftSync)
                this.TestSite.Assert.IsTrue(isClientSupportSoftSync, "SUT should support Soft-Sync.");

            // Init for capability exchange
            RDPEGFX_CapabilityExchange(transport, isSoftSync);

            // Create a surface
            RDPGFX_RECT16 surfRect = RdpegfxTestUtility.ConvertToRect(RdpegfxTestUtility.surfPos, RdpegfxTestUtility.surfWidth, RdpegfxTestUtility.surfHeight);
            Surface surf = this.rdpegfxAdapter.CreateAndOutputSurface(surfRect, PixelFormat.PIXEL_FORMAT_ARGB_8888);
            this.TestSite.Assert.IsNotNull(surf, "Surface {0} is created", surf.Id);

            // Build muliple cache to surface messages to cover the surface by cacheRect
            ushort cacheW = (ushort)(RdpegfxTestUtility.cacheRect.right - RdpegfxTestUtility.cacheRect.left);
            ushort cacheH = (ushort)(RdpegfxTestUtility.cacheRect.bottom - RdpegfxTestUtility.cacheRect.top);

            ushort currRectTop = 0;

            List<RDPGFX_POINT16> destPointList = new List<RDPGFX_POINT16>();
            while (currRectTop < surf.Height)
            {
                ushort currRectLeft = 0;
                while (currRectLeft < surf.Width)
                {
                    RDPGFX_POINT16 pos = new RDPGFX_POINT16(currRectLeft, currRectTop);
                    destPointList.Add(pos);
                    currRectLeft += cacheW;
                }
                currRectTop += cacheH;
            }

            uint fid = this.rdpegfxAdapter.FillSurfaceByCachedBitmap(surf, RdpegfxTestUtility.cacheRect, RdpegfxTestUtility.cacheKey, destPointList.ToArray(), null, RdpegfxTestUtility.fillColorRed);
            this.TestSite.Log.Add(LogEntryKind.Debug, "Surface is filled by cached bitmap in frame: {0}", fid);

            this.rdpegfxAdapter.ExpectFrameAck(fid);

            this.TestSite.Log.Add(LogEntryKind.Comment, "Verify output on SUT Display if the verifySUTDisplay entry in PTF config is true.");
            this.VerifySUTDisplay(false, surfRect);

            // Delete the surface after wait 3 seconds.
            this.rdpegfxAdapter.DeleteSurface(surf.Id);
            this.TestSite.Log.Add(LogEntryKind.Debug, "Surface {0} is deleted", surf.Id);
        }
        /// <summary>
        /// Copy bitmap data from a source surface to a destination surface 
        /// or to replicate bitmap data within the same surface.
        /// </summary>
        /// <param name="surfaceIdSrc"></param>
        /// <param name="surfaceIdDest"></param>
        /// <param name="rectSrc"></param>
        /// <param name="destPts"></param>
        public void SurfaceToSurface(ushort surfaceIdSrc, ushort surfaceIdDest, RDPGFX_RECT16 rectSrc, RDPGFX_POINT16[] destPts)
        {
            if (surfaceDic.ContainsKey(surfaceIdSrc) && surfaceDic.ContainsKey(surfaceIdDest))
            {
                if (destPts != null && destPts.Length > 0)
                {
                    Surface surfaceSrc = surfaceDic[surfaceIdSrc];
                    Surface surfaceDest = surfaceDic[surfaceIdDest];

                    foreach (RDPGFX_POINT16 destPt in destPts)
                    {
                        surfaceDest.DrawImage(surfaceSrc.Image, destPt.x, destPt.y, rectSrc);
                    }
                }
            }
        }
 /// <summary>
 /// Load a residual layer bitmap into clearcode encoder.   
 /// </summary>
 /// <param name = "bandBitmap"> specifies a band layer image </param>
 /// <param name = "pos"> specifies position of band layer image, relative to residual layer image </param>
 public void LoadBandBitmap(Bitmap bandBitmap, RDPGFX_POINT16 pos)
 {
     if (bandBitmap != null)
     {
         ClearCodec_RECT16 bRect = new ClearCodec_RECT16();
         bRect.left = pos.x;
         bRect.top = pos.y;
         bRect.right = (ushort)(pos.x + bandBitmap.Width);
         bRect.bottom = (ushort)(pos.y + bandBitmap.Height);
         this.bandDict.Add(bRect, bandBitmap);
     }
 }
        public void RDPEGFX_SurfaceToScreen_PositiveTest_MultiSurfaceOverlap()
        {
            uint fid;

            this.TestSite.Log.Add(LogEntryKind.Comment, "Do capability exchange.");
            // Init for capability exchange
            RDPEGFX_CapabilityExchange();

            RDPGFX_RECT16 verifyRect = RdpegfxTestUtility.ConvertToRect(RdpegfxTestUtility.surfPos, RdpegfxTestUtility.surfWidth, RdpegfxTestUtility.surfHeight);

            // Init Data for test
            RDPGFX_POINT16[] positions = new RDPGFX_POINT16[4];
            positions[0] = new RDPGFX_POINT16(RdpegfxTestUtility.surfPos.x, RdpegfxTestUtility.surfPos.y);
            positions[1] = new RDPGFX_POINT16((ushort)(RdpegfxTestUtility.surfPos.x + RdpegfxTestUtility.surfWidth/2), RdpegfxTestUtility.surfPos.y);
            positions[2] = new RDPGFX_POINT16(RdpegfxTestUtility.surfPos.x, (ushort)(RdpegfxTestUtility.surfPos.y + RdpegfxTestUtility.surfHeight / 2));
            positions[3] = new RDPGFX_POINT16(RdpegfxTestUtility.surfPos.x, RdpegfxTestUtility.surfPos.y);

            ushort[] widths = new ushort[4];
            widths[0] = RdpegfxTestUtility.surfWidth;
            widths[1] = (ushort)(RdpegfxTestUtility.surfWidth / 2);
            widths[2] = RdpegfxTestUtility.surfWidth;
            widths[3] = (ushort)(RdpegfxTestUtility.surfWidth / 2);

            ushort[] heights = new ushort[4];
            heights[0] = (ushort)(RdpegfxTestUtility.surfHeight / 2);
            heights[1] = RdpegfxTestUtility.surfHeight;
            heights[2] = (ushort)(RdpegfxTestUtility.surfHeight / 2);
            heights[3] = RdpegfxTestUtility.surfHeight;

            Color[] colors = new Color[4];
            colors[0] = Color.Green;
            colors[1] = Color.Blue;
            colors[2] = Color.Red;
            colors[3] = Color.Yellow;

            Surface[] surfaces = new Surface[4];
            // Test the overlap
            for (int i = 0; i < positions.Length; i++)
            {
                this.TestSite.Log.Add(LogEntryKind.Comment, "Create a surface and fill it with color: {0}.", colors[i]);
                // Create & output a surface
                RDPGFX_RECT16 surfRect = RdpegfxTestUtility.ConvertToRect(positions[i], widths[i], heights[i]);
                surfaces[i] = this.rdpegfxAdapter.CreateAndOutputSurface(surfRect, PixelFormat.PIXEL_FORMAT_XRGB_8888);
                this.TestSite.Assert.IsNotNull(surfaces[i], "Surface {0} is created", surfaces[i].Id);

                // Send solid fill request to client to fill surface with green color
                RDPGFX_RECT16 fillSurfRect = RdpegfxTestUtility.ConvertToRect(RdpegfxTestUtility.imgPos, widths[i], heights[i]);
                RDPGFX_RECT16[] fillRects = { fillSurfRect };  // Relative to surface
                fid = this.rdpegfxAdapter.SolidFillSurface(surfaces[i], RdpegfxTestUtility.ToRdpgfx_Color32(colors[i]), fillRects);
                this.TestSite.Log.Add(LogEntryKind.Debug, "Surface is filled with solid color in frame: {0}", fid);

                // Expect the client to send a frame acknowledge pdu
                // If the server receives the message, it indicates that the client has been successfully decoded the logical frame of graphics commands
                this.rdpegfxAdapter.ExpectFrameAck(fid);

                this.TestSite.Log.Add(LogEntryKind.Comment, "Verify output on SUT Display if the verifySUTDisplay entry in PTF config is true.");
                this.VerifySUTDisplay(false, verifyRect);
            }
            // Delete the surface
            for (int i = 0; i < surfaces.Length; i++)
            {
                if (surfaces[i] != null)
                {
                    this.rdpegfxAdapter.DeleteSurface(surfaces[i].Id);
                    this.TestSite.Log.Add(LogEntryKind.Debug, "Surface {0} is deleted", surfaces[i].Id);
                }
            }
        }
 /// <summary>
 /// Load a residual layer bitmap into clearcode encoder.   
 /// </summary>
 /// <param name = "subcodecBitmap"> specifies a subcodec layer image </param>
 /// <param name = "pos"> specifies position of subcodec layer image, relative to residual layer image </param>
 /// <param name = "sbcID"> specifies subcodec ID to encoding subcodec layer image </param>
 public void LoadSubcodecBitmap(Bitmap subcodecBitmap, RDPGFX_POINT16 pos, CLEARCODEC_SUBCODEC_ID sbcID)
 {
     if (subcodecBitmap != null)
     {
         ClearCodec_RECT16 scRect = new ClearCodec_RECT16();
         scRect.left = pos.x;
         scRect.top = pos.y;
         scRect.right = (ushort)(pos.x + subcodecBitmap.Width);
         scRect.bottom = (ushort)(pos.x + subcodecBitmap.Height);
         BMP_INFO bmp_info = new BMP_INFO();
         bmp_info.bmp = subcodecBitmap;
         bmp_info.scID = sbcID;
         this.subcodecDict.Add(scRect, bmp_info);
     }
 }
        /// <summary>
        /// Method to make a surface to surface Pdu.
        /// </summary>
        /// <param name="srcSID">This is used to indicate source surface id.</param>
        /// <param name="destSID">This is used to indicate destination surface id.</param>
        /// <param name="srcRect">This is used to indicate source rectangle bitmap area to be copied.</param>
        /// <param name="destPoints">This is used to specify destination points of source rectangle bitmap to be copied </param>
        void MakeSurfaceToSurfacePdu(ushort srcSID, ushort destSID, RDPGFX_RECT16 srcRect, RDPGFX_POINT16[] destPoints)
        {
            RDPGFX_SURFACE_TO_SURFACE surfToSurf = egfxServer.CreateSurfaceToSurfacePdu(srcSID, destSID, srcRect, destPoints);
            // Change pdu based testtype
            if (currentTestType == RdpegfxNegativeTypes.SurfaceManagement_InterSurfaceCopy_InexistentSrc)
            {
                surfToSurf.surfaceIdSrc = 0xffff; // 0xffff is an inexistent surface id.
            }
            else if (currentTestType == RdpegfxNegativeTypes.SurfaceManagement_InterSurfaceCopy_InexistentDest)
            {
                surfToSurf.surfaceIdDest = 0xffff; // 0xffff is an inexistent surface id.
            }
            else if (currentTestType == RdpegfxNegativeTypes.SurfaceManagement_InterSurfaceCopy_DestPtsCount_Mismatch)
            {
                surfToSurf.destPtsCount += 1; // Make the value of destPts and the length of destPts mismatch.
            }

            AddPdusToBuffer(surfToSurf);

            if (this.bcgrAdapter.SimulatedScreen != null)
            {
                this.bcgrAdapter.SimulatedScreen.SurfaceToSurface(srcSID, destSID, srcRect, destPoints);
            }
        }
        /// <summary>
        /// Capture a bitmap from an image
        /// </summary>
        /// <param name="srcImage"> The source of captured bitmap </param>
        /// <param name="capPos"> Left-top position in source image for captured bitmap  </param>
        /// <param name="width"> Width of captured bitmap </param>
        /// <param name="height"> Height of captured bitmap </param>
        /// <param name="bgImage"> The image after a part is captured </param>
        /// <returns> The captured bitmap </returns>
        public static Bitmap captureFromImage(Image srcImage, RDPGFX_POINT16 capPos, int width, int height, out Image bgImage)
        {
            // Cut a bitmap(width * height) from position(left,top) of srcImage
            Bitmap bitmap = new Bitmap(width, height);
            Graphics g = Graphics.FromImage(bitmap);
            Rectangle destRect = new Rectangle(0, 0, width, height);
            Rectangle srcRect = new Rectangle(capPos.x, capPos.y, width, height);
            g.DrawImage(srcImage, destRect, srcRect, GraphicsUnit.Pixel);

            // Fill the cut rectangle with solid color at position(left, top)
            bgImage = srcImage;
            Bitmap bgBmp = (Bitmap)bgImage;
            Color brushColor = bgBmp.GetPixel(capPos.x, capPos.y);
            SolidBrush pixelBrush = new SolidBrush(brushColor);
            Graphics srcg = Graphics.FromImage(srcImage);
            srcg.FillRectangle(pixelBrush, srcRect);
            return bitmap;
        }
        /// <summary>
        /// Method to implement SurfaceToCache and CacheToSurface functionality.
        /// </summary>
        /// <param name="surf">The surface to be filled.</param>
        /// <param name="cacheRect">The rectangle to be cached on the surface.</param>
        /// <param name="cacheKey">The cacheKey of rectangle bitmap data on client.</param>
        /// <param name="destPoints">This is used to specify destination points of source rectangle bitmap to be copied </param>
        /// <param name="cacheSlot">Specify a cacheslot</param>
        /// <param name="fillColor">The color that rectangle to be filled.</param>
        /// <returns> Frame Id </returns>
        public uint FillSurfaceByCachedBitmap(Surface surf, RDPGFX_RECT16 cacheRect, ulong cacheKey, RDPGFX_POINT16[] destPoints, ushort? cacheSlot, RDPGFX_COLOR32? fillColor = null)
        {
            uint fid = MakeStartFramePdu();

            if (fillColor != null)
            {
                // Send solid fill request to client to fill cacheRect of surface with color
                RDPGFX_RECT16[] rects = { cacheRect };
                MakeSolidFillPdu(surf.Id, fillColor.Value, rects);
            }

            // Copy a rectangle bitmap data to cache and move it from cache to other positions of surface.
            if (cacheSlot == null)
            {
                cacheSlot = 1;  //set slot# to 1
            }
            MakeSurfaceToCachePdu(surf.Id, cacheKey, cacheSlot.Value, cacheRect);

            if (currentTestType == RdpegfxNegativeTypes.CacheManagement_CacheToSurface_InexistentCacheSlot)
            {
                cacheSlot = (ushort)(cacheSlot.Value + 1);
            }
            ushort sid = surf.Id;
            if (currentTestType == RdpegfxNegativeTypes.CacheManagement_CacheToSurface_InexistentSurface)
            {
                sid++;
            }
            MakeCacheToSurfacePdu(cacheSlot.Value, sid, destPoints);

            MakeEndFramePdu(fid);

            PackAndSendServerPdu();
            return fid;
        }
 /// <summary>
 /// Convert a position and width/height into Rectangle structure
 /// </summary>
 /// <param name="pos"> Left-top position of a rectangle </param>
 /// <param name="width"> Width of a rectangle </param>
 /// <param name="height"> Height of a rectangle </param>
 /// <returns> Converted rectangle </returns>
 public static RDPGFX_RECT16 ConvertToRect(RDPGFX_POINT16 pos, ushort width, ushort height)
 {
     return new RDPGFX_RECT16(pos.x, pos.y, (ushort)(pos.x + width), (ushort)(pos.y + height));
 }
        /// <summary>
        /// Method to copy bitmap of a rectangle in surface to other position
        /// </summary>
        /// <param name="surf">The source surface where the rectangle to be copied.</param>
        /// <param name="srcRect">The rectangle to be copied.</param>
        /// <param name="destPos">The position array that rectangle is copied to.</param>
        /// <returns> Frame Id </returns>
        public uint IntraSurfaceCopy(Surface surf, RDPGFX_RECT16 srcRect, RDPGFX_POINT16[] destPos)
        {
            uint fid = MakeStartFramePdu();
            MakeSurfaceToSurfacePdu(surf.Id, surf.Id, srcRect, destPos);
            MakeEndFramePdu(fid);

            PackAndSendServerPdu();

            return fid;
        }
        /// <summary>
        /// Draw an image for surface, which has a bitmap in surface.
        /// </summary>
        /// <param name="surf"> Indicate the size of surface image </param>
        /// <param name="bgcolor"> Indicate the background color of surface image </param>
        /// <param name="pic"> The bitmap to be drawn in surface image </param>
        /// <param name="picPos"> The bitmap position in surface </param>
        /// <returns> A surface image </returns>
        public static Bitmap DrawSurfImage(Surface surf, Color bgcolor, Bitmap pic, RDPGFX_POINT16 picPos)
        {
            Bitmap bitmap = new Bitmap(surf.Width, surf.Height);
            Graphics g = Graphics.FromImage(bitmap);
            SolidBrush pixelBrush = new SolidBrush(bgcolor);
            g.FillRectangle(pixelBrush, 0, 0, surf.Width, surf.Height);
            for (int x = picPos.x; (x < surf.Width) && (x < (picPos.x + pic.Width)); x++)
            {
                for (int y = picPos.y; (y < surf.Height) && (y < (picPos.y + pic.Height)); y++)
                {
                    Color c = pic.GetPixel(x - picPos.x, y - picPos.y);
                    bitmap.SetPixel(x, y, c);
                }
            }

            return bitmap;
        }
        /// <summary>
        /// Send clearcodec encoded glyph in batch (make sure glyphnum + startGlyphRect.right is not bigger than surf.width)
        /// </summary>
        /// <param name="surf">This is used to indicate the target surface id.</param>
        /// <param name="startGlyphIdx">This is used to indicate the start index of graph batch to be put in client graph cache.</param>
        /// <param name="startGlyphPos">The start position of glyph batch, which will be sent in clearcodec, relative to the surface. </param>
        /// <param name="glyphNum"> The glyph number in batch. </param>
        /// <param name="glyph"> The residual layer image to be sent. </param>
        /// <returns> Frame Id </returns>
        public uint SendClearCodecGlyphInBatch(Surface surf, ushort startGlyphIdx, RDPGFX_POINT16 startGlyphPos, ushort glyphNum, Image glyph)
        {
            uint fid = MakeStartFramePdu();

            ushort glyphIdx = startGlyphIdx;
            RDPGFX_RECT16 glyphRect = new RDPGFX_RECT16(startGlyphPos.x, startGlyphPos.y,
                                            (ushort)(startGlyphPos.x + glyph.Width),
                                            (ushort)(startGlyphPos.y + glyph.Height));

            // Pack multiple w2s_1 PDU into a frame.
            for (ushort i = 0; i < glyphNum; i++)
            {
                ClearCodec_BitmapStream ccStream = new ClearCodec_BitmapStream(ClearCodec_BitmapStream.CLEARCODEC_FLAG_GLYPH_INDEX, glyphIdx);
                ccStream.LoadResidualBitmap((Bitmap)glyph);
                ccStream.seqNumber = egfxServer.Get_ClearCodecBitmapStream_SeqNum();
                MakeWireToSurfacePdu1(surf.Id, CodecType.RDPGFX_CODECID_CLEARCODEC, PixelFormat.PIXEL_FORMAT_XRGB_8888,
                                        glyphRect, ccStream.Encode());
                glyphIdx++;
                glyphRect.left++;
                glyphRect.right++;
            }

            MakeEndFramePdu(fid);

            PackAndSendServerPdu();

            if (this.bcgrAdapter.SimulatedScreen != null)
            {
                this.bcgrAdapter.SimulatedScreen.RenderClearCodecBatch(surf.Id, startGlyphIdx, startGlyphPos, glyphNum, glyph);
            }

            return fid;
        }
        /// <summary>
        /// Common function to send H264 data to the client
        /// </summary>
        /// <param name="h264DataFile">XML file of H264 data</param>
        /// <param name="isAVC444">Whether need RDP client support AVC444</param>
        private void SendH264CodecStream(string h264DataFile, bool isAVC444)
        {
            //Load H264 data
            RdpegfxH264TestDatas h264TestData = GetH264TestData(h264DataFile);

            // Init for capability exchange
            this.TestSite.Log.Add(LogEntryKind.Comment, "Do capability exchange.");
            RDPEGFX_CapabilityExchange();
            if (isAVC444)
            {
                this.TestSite.Assume.IsTrue(this.isH264AVC444Supported, "This test case need RDP client indicate support AVC444(RDPGFX_CAPSET_VERSION10,RDPGFX_CAPSET_VERSION102).");
            }
            else
            {
                this.TestSite.Assume.IsTrue(this.isH264AVC420Supported, "To test H264 codec, client must indicates support for H264 codec in RDPGFX_CAPS_ADVERTISE_PDU");
            }

            this.TestSite.Log.Add(LogEntryKind.Comment, "Create a surface and fill it with green color.");
            // Create & output a surface
            RDPGFX_POINT16 surfPos = new RDPGFX_POINT16((ushort)h264TestData.SurfaceInfo.outputOriginX, (ushort)h264TestData.SurfaceInfo.outputOriginY);
            RDPGFX_RECT16 surfRect = RdpegfxTestUtility.ConvertToRect(surfPos, h264TestData.SurfaceInfo.width, h264TestData.SurfaceInfo.height);
            RDPGFX_RECT16 compareRect = RdpegfxTestUtility.ConvertToRect(surfPos, h264TestData.SurfaceInfo.width, h264TestData.SurfaceInfo.height);
            if (isWindowsImplementation && compareRect.top < 32 && compareRect.bottom >32)
            {
                // Ignore the field of RDP client connection bar
                compareRect.top = 32;
            }
            Surface surf = this.rdpegfxAdapter.CreateAndOutputSurface(surfRect, (PixelFormat)h264TestData.SurfaceInfo.pixelFormat);
            this.TestSite.Assert.IsNotNull(surf, "Surface {0} is created", surf.Id);

            // Send solid fill request to client to fill surface with green color
            RDPGFX_RECT16[] fillRects = { new RDPGFX_RECT16(h264TestData.TestDataList[0].DestRect.left,
                h264TestData.TestDataList[0].DestRect.top,
                h264TestData.TestDataList[0].DestRect.right,
                h264TestData.TestDataList[0].DestRect.bottom)};  // Relative to surface
            uint fid = this.rdpegfxAdapter.SolidFillSurface(surf, RdpegfxTestUtility.fillColorGreen, fillRects);
            this.TestSite.Log.Add(LogEntryKind.Debug, "Surface is filled with solid color in frame: {0}", fid);
            this.rdpegfxAdapter.ExpectFrameAck(fid);

            // Send H264 codec data
            foreach (TestData data in h264TestData.TestDataList)
            {
                ushort codecId = data.codecId;
                PixelFormat pixFormat = (PixelFormat)data.pixelFormat;
                RDPGFX_RECT16 bmRect = new RDPGFX_RECT16();
                bmRect.left = data.DestRect.left;
                bmRect.top = data.DestRect.top;
                bmRect.right = data.DestRect.right;
                bmRect.bottom = data.DestRect.bottom;

                if (codecId == (ushort)CodecType.RDPGFX_CODECID_AVC420 && data.AVC420BitmapStream != null)
                {

                    this.TestSite.Log.Add(LogEntryKind.Comment, "Sending H264 AVC420 Encoded Bitmap Data Messages to client.");
                    fid = this.rdpegfxAdapter.SendImageWithH264AVC420Codec(surf.Id, pixFormat, bmRect, data.AVC420BitmapStream.To_RFX_AVC420_BITMAP_STREAM(), data.GetBaseImage());
                    // Test case pass if frame acknowledge is received.
                    this.rdpegfxAdapter.ExpectFrameAck(fid);
                }
                else if (codecId == (ushort)CodecType.RDPGFX_CODECID_AVC444 && data.AVC444BitmapStream != null)
                {
                    this.TestSite.Log.Add(LogEntryKind.Comment, "Sending H264 AVC444 Encoded Bitmap Data Messages to client.");
                    fid = this.rdpegfxAdapter.SendImageWithH264AVC444Codec(surf.Id, pixFormat, bmRect, data.AVC444BitmapStream.To_RFX_AVC444_BITMAP_STREAM(), data.GetBaseImage());
                    // Test case pass if frame acknowledge is received.
                    this.rdpegfxAdapter.ExpectFrameAck(fid);
                }
                else
                {
                    Site.Assert.Fail("Test data doesn't contain proper H264 encoded data corresponding to codec ID.");
                }

                this.TestSite.Log.Add(LogEntryKind.Comment, "Verify output on SUT Display if the verifySUTDisplay entry in PTF config is true.");
                this.VerifySUTDisplay(true, compareRect, 2);

            }

            // Delete the surface
            this.rdpegfxAdapter.DeleteSurface(surf.Id);
            this.TestSite.Log.Add(LogEntryKind.Debug, "Surface {0} is deleted", surf.Id);
        }